Changeset 253 in code for trunk/upstream.go


Ignore:
Timestamp:
Apr 10, 2020, 5:22:47 PM (5 years ago)
Author:
contact
Message:

Per-entity ring buffers

Instead of having one ring buffer per network, each network has one ring
buffer per entity (channel or nick). This allows history to be more
fair: if there's a lot of activity in a channel, it won't prune activity
in other channels.

We now track history sequence numbers per client and per network in
networkHistory. The overall list of offline clients is still tracked in
network.offlineClients.

When all clients have received history, the ring buffer can be released.

In the future, we should get rid of too-old offline clients to avoid
having to maintain history for them forever. We should also add a
per-user limit on the number of ring buffers.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/upstream.go

    r248 r253  
    557557                                ch.Members[newNick] = membership
    558558                                uc.appendLog(ch.Name, msg)
     559                                uc.appendHistory(ch.Name, msg)
    559560                        }
    560561                }
    561562
    562563                if !me {
    563                         uc.network.ring.Produce(msg)
    564564                        uc.forEachDownstream(func(dc *downstreamConn) {
    565565                                dc.SendMessage(dc.marshalMessage(msg, uc))
     
    663663
    664664                                uc.appendLog(ch.Name, msg)
     665                                uc.appendHistory(ch.Name, msg)
    665666                        }
    666667                }
    667668
    668669                if msg.Prefix.Name != uc.nick {
    669                         uc.network.ring.Produce(msg)
    670670                        uc.forEachDownstream(func(dc *downstreamConn) {
    671671                                dc.SendMessage(dc.marshalMessage(msg, uc))
     
    12951295}
    12961296
     1297// appendHistory appends a message to the history. entity can be empty.
     1298func (uc *upstreamConn) appendHistory(entity string, msg *irc.Message) {
     1299        // If no client is offline, no need to append the message to the buffer
     1300        if len(uc.network.offlineClients) == 0 {
     1301                return
     1302        }
     1303
     1304        history, ok := uc.network.history[entity]
     1305        if !ok {
     1306                history = &networkHistory{
     1307                        offlineClients: make(map[string]uint64),
     1308                        ring:           NewRing(uc.srv.RingCap),
     1309                }
     1310                uc.network.history[entity] = history
     1311
     1312                for clientName, _ := range uc.network.offlineClients {
     1313                        history.offlineClients[clientName] = 0
     1314                }
     1315        }
     1316
     1317        history.ring.Produce(msg)
     1318}
     1319
    12971320// produce appends a message to the logs, adds it to the history and forwards
    12981321// it to connected downstream connections.
     
    13051328        }
    13061329
    1307         uc.network.ring.Produce(msg)
     1330        uc.appendHistory(target, msg)
    13081331
    13091332        uc.forEachDownstream(func(dc *downstreamConn) {
Note: See TracChangeset for help on using the changeset viewer.