Changeset 489 in code for trunk/user.go


Ignore:
Timestamp:
Mar 31, 2021, 4:04:13 PM (4 years ago)
Author:
contact
Message:

Save delivery receipts in DB

This avoids loosing history on restart for clients that don't
support chathistory.

Closes: https://todo.sr.ht/~emersion/soju/80

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/user.go

    r487 r489  
    9090        for _, entry := range ds.m.innerMap {
    9191                f(entry.originalKey)
     92        }
     93}
     94
     95func (ds deliveredStore) ForEachClient(f func(clientName string)) {
     96        clients := make(map[string]struct{})
     97        for _, entry := range ds.m.innerMap {
     98                delivered := entry.value.(deliveredClientMap)
     99                for clientName := range delivered {
     100                        clients[clientName] = struct{}{}
     101                }
     102        }
     103
     104        for clientName := range clients {
     105                f(clientName)
    92106        }
    93107}
     
    299313}
    300314
     315func (net *network) storeClientDeliveryReceipts(clientName string) {
     316        if !net.user.hasPersistentMsgStore() {
     317                return
     318        }
     319
     320        var receipts []DeliveryReceipt
     321        net.delivered.ForEachTarget(func(target string) {
     322                msgID := net.delivered.LoadID(target, clientName)
     323                if msgID == "" {
     324                        return
     325                }
     326                receipts = append(receipts, DeliveryReceipt{
     327                        Target:        target,
     328                        InternalMsgID: msgID,
     329                })
     330        })
     331
     332        if err := net.user.srv.db.StoreClientDeliveryReceipts(net.ID, clientName, receipts); err != nil {
     333                net.user.srv.Logger.Printf("failed to store delivery receipts for user %q, client %q, network %q: %v", net.user.Username, clientName, net.GetName(), err)
     334        }
     335}
     336
    301337type user struct {
    302338        User
     
    309345        downstreamConns []*downstreamConn
    310346        msgStore        messageStore
    311         clientNames     map[string]struct{}
    312347
    313348        // LIST commands in progress
     
    330365
    331366        return &user{
    332                 User:        *record,
    333                 srv:         srv,
    334                 events:      make(chan event, 64),
    335                 done:        make(chan struct{}),
    336                 msgStore:    msgStore,
    337                 clientNames: make(map[string]struct{}),
     367                User:     *record,
     368                srv:      srv,
     369                events:   make(chan event, 64),
     370                done:     make(chan struct{}),
     371                msgStore: msgStore,
    338372        }
    339373}
     
    407441                network := newNetwork(u, &record, channels)
    408442                u.networks = append(u.networks, network)
     443
     444                if u.hasPersistentMsgStore() {
     445                        receipts, err := u.srv.db.ListDeliveryReceipts(record.ID)
     446                        if err != nil {
     447                                u.srv.Logger.Printf("failed to load delivery receipts for user %q, network %q: %v", u.Username, network.GetName(), err)
     448                                return
     449                        }
     450
     451                        for _, rcpt := range receipts {
     452                                network.delivered.StoreID(rcpt.Target, rcpt.Client, rcpt.InternalMsgID)
     453                        }
     454                }
    409455
    410456                go network.run()
     
    490536                                uc.updateAway()
    491537                        })
    492 
    493                         u.clientNames[dc.clientName] = struct{}{}
    494538                case eventDownstreamDisconnected:
    495539                        dc := e.dc
     
    501545                                }
    502546                        }
     547
     548                        dc.forEachNetwork(func(net *network) {
     549                                net.storeClientDeliveryReceipts(dc.clientName)
     550                        })
    503551
    504552                        u.forEachUpstream(func(uc *upstreamConn) {
     
    525573                        for _, n := range u.networks {
    526574                                n.stop()
     575
     576                                n.delivered.ForEachClient(func(clientName string) {
     577                                        n.storeClientDeliveryReceipts(clientName)
     578                                })
    527579                        }
    528580                        return
     
    666718        <-u.done
    667719}
     720
     721func (u *user) hasPersistentMsgStore() bool {
     722        if u.msgStore == nil {
     723                return false
     724        }
     725        _, isMem := u.msgStore.(*memoryMessageStore)
     726        return !isMem
     727}
Note: See TracChangeset for help on using the changeset viewer.