Replace networkHistory.offlineClients with clients

Keep the ring buffer alive even if all clients are connected. Keep the
ID of the latest delivered message even for online clients.

As-is, this is a net downgrade: memory usage increases because ring
buffers aren't free'd anymore. However upcoming commits will replace the
ring buffer with log files. This change makes reading from log files
easier.
This commit is contained in:
Simon Ser 2020-08-11 17:12:06 +02:00
parent 81c7e80e0f
commit 4dae0da59f
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
3 changed files with 14 additions and 28 deletions

View File

@ -864,17 +864,11 @@ func (dc *downstreamConn) sendNetworkHistory(net *network) {
continue
}
seq, ok := history.offlineClients[dc.clientName]
seq, ok := history.clients[dc.clientName]
if !ok {
continue
}
delete(history.offlineClients, dc.clientName)
// If all clients have received history, no need to keep the
// ring buffer around
if len(history.offlineClients) == 0 {
delete(net.history, target)
}
history.clients[dc.clientName] = history.ring.Cur()
consumer := history.ring.NewConsumer(seq)

View File

@ -1635,33 +1635,34 @@ func (uc *upstreamConn) appendHistory(entity string, msg *irc.Message) {
detached = ch.Detached
}
// If no client is offline, no need to append the message to the buffer
if len(uc.network.offlineClients) == 0 && !detached {
return
}
history, ok := uc.network.history[entity]
if !ok {
history = &networkHistory{
offlineClients: make(map[string]uint64),
ring: NewRing(uc.srv.RingCap),
clients: make(map[string]uint64),
ring: NewRing(uc.srv.RingCap),
}
uc.network.history[entity] = history
for clientName, _ := range uc.network.offlineClients {
history.offlineClients[clientName] = 0
history.clients[clientName] = 0
}
if detached {
// If the channel is detached, online clients act as offline
// clients too
uc.forEachDownstream(func(dc *downstreamConn) {
history.offlineClients[dc.clientName] = 0
history.clients[dc.clientName] = 0
})
}
}
history.ring.Produce(msg)
if !detached {
uc.forEachDownstream(func(dc *downstreamConn) {
history.clients[dc.clientName] = history.ring.Cur()
})
}
}
// produce appends a message to the logs, adds it to the history and forwards

13
user.go
View File

@ -51,8 +51,8 @@ type eventDownstreamDisconnected struct {
type eventStop struct{}
type networkHistory struct {
offlineClients map[string]uint64 // indexed by client name
ring *Ring // can be nil if there are no offline clients
clients map[string]uint64 // indexed by client name
ring *Ring // can be nil if there are no offline clients
}
type network struct {
@ -193,9 +193,6 @@ func (net *network) createUpdateChannel(ch *Channel) error {
net.user.srv.Logger.Printf("network %q: detaching channel %q", net.GetName(), ch.Name)
net.forEachDownstream(func(dc *downstreamConn) {
net.offlineClients[dc.clientName] = struct{}{}
if history != nil {
history.offlineClients[dc.clientName] = history.ring.Cur()
}
dc.SendMessage(&irc.Message{
Prefix: dc.prefix(),
@ -423,12 +420,6 @@ func (u *user) run() {
}
net.offlineClients[dc.clientName] = struct{}{}
for target, history := range net.history {
if ch, ok := net.channels[target]; ok && ch.Detached {
continue
}
history.offlineClients[dc.clientName] = history.ring.Cur()
}
})
u.forEachUpstream(func(uc *upstreamConn) {