diff --git a/db.go b/db.go index e2c90a7..4147a7c 100644 --- a/db.go +++ b/db.go @@ -109,10 +109,12 @@ func parseFilter(filter string) (MessageFilter, error) { } type Channel struct { - ID int64 - Name string - Key string - Detached bool + ID int64 + Name string + Key string + + Detached bool + DetachedInternalMsgID string RelayDetached MessageFilter ReattachOn MessageFilter @@ -161,6 +163,7 @@ CREATE TABLE Channel ( name VARCHAR(255) NOT NULL, key VARCHAR(255), detached INTEGER NOT NULL DEFAULT 0, + detached_internal_msgid VARCHAR(255), relay_detached INTEGER NOT NULL DEFAULT 0, reattach_on INTEGER NOT NULL DEFAULT 0, detach_after INTEGER NOT NULL DEFAULT 0, @@ -245,6 +248,7 @@ var migrations = []string{ UNIQUE(network, target, client) ); `, + "ALTER TABLE Channel ADD COLUMN detached_internal_msgid VARCHAR(255)", } type DB struct { @@ -546,7 +550,9 @@ func (db *DB) ListChannels(networkID int64) ([]Channel, error) { db.lock.RLock() defer db.lock.RUnlock() - rows, err := db.db.Query(`SELECT id, name, key, detached, relay_detached, reattach_on, detach_after, detach_on + rows, err := db.db.Query(`SELECT + id, name, key, detached, detached_internal_msgid, + relay_detached, reattach_on, detach_after, detach_on FROM Channel WHERE network = ?`, networkID) if err != nil { @@ -557,12 +563,13 @@ func (db *DB) ListChannels(networkID int64) ([]Channel, error) { var channels []Channel for rows.Next() { var ch Channel - var key sql.NullString + var key, detachedInternalMsgID sql.NullString var detachAfter int64 - if err := rows.Scan(&ch.ID, &ch.Name, &key, &ch.Detached, &ch.RelayDetached, &ch.ReattachOn, &detachAfter, &ch.DetachOn); err != nil { + if err := rows.Scan(&ch.ID, &ch.Name, &key, &ch.Detached, &detachedInternalMsgID, &ch.RelayDetached, &ch.ReattachOn, &detachAfter, &ch.DetachOn); err != nil { return nil, err } ch.Key = key.String + ch.DetachedInternalMsgID = detachedInternalMsgID.String ch.DetachAfter = time.Duration(detachAfter) * time.Second channels = append(channels, ch) } @@ -583,14 +590,14 @@ func (db *DB) StoreChannel(networkID int64, ch *Channel) error { var err error if ch.ID != 0 { _, err = db.db.Exec(`UPDATE Channel - SET network = ?, name = ?, key = ?, detached = ?, relay_detached = ?, reattach_on = ?, detach_after = ?, detach_on = ? + SET network = ?, name = ?, key = ?, detached = ?, detached_internal_msgid = ?, relay_detached = ?, reattach_on = ?, detach_after = ?, detach_on = ? WHERE id = ?`, - networkID, ch.Name, key, ch.Detached, ch.RelayDetached, ch.ReattachOn, detachAfter, ch.DetachOn, ch.ID) + networkID, ch.Name, key, ch.Detached, toNullString(ch.DetachedInternalMsgID), ch.RelayDetached, ch.ReattachOn, detachAfter, ch.DetachOn, ch.ID) } else { var res sql.Result - res, err = db.db.Exec(`INSERT INTO Channel(network, name, key, detached, relay_detached, reattach_on, detach_after, detach_on) + res, err = db.db.Exec(`INSERT INTO Channel(network, name, key, detached, detached_internal_msgid, relay_detached, reattach_on, detach_after, detach_on) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, - networkID, ch.Name, key, ch.Detached, ch.RelayDetached, ch.ReattachOn, detachAfter, ch.DetachOn) + networkID, ch.Name, key, ch.Detached, toNullString(ch.DetachedInternalMsgID), ch.RelayDetached, ch.ReattachOn, detachAfter, ch.DetachOn) if err != nil { return err } diff --git a/user.go b/user.go index 8052234..e2e06ee 100644 --- a/user.go +++ b/user.go @@ -232,9 +232,20 @@ func (net *network) detach(ch *Channel) { if ch.Detached { return } - ch.Detached = true + net.user.logger.Printf("network %q: detaching channel %q", net.GetName(), ch.Name) + ch.Detached = true + + if net.user.msgStore != nil { + nameCM := net.casemap(ch.Name) + lastID, err := net.user.msgStore.LastMsgID(net, nameCM, time.Now()) + if err != nil { + net.user.logger.Printf("failed to get last message ID for channel %q: %v", ch.Name, err) + } + ch.DetachedInternalMsgID = lastID + } + if net.conn != nil { uch := net.conn.channels.Value(ch.Name) if uch != nil { @@ -255,9 +266,13 @@ func (net *network) attach(ch *Channel) { if !ch.Detached { return } - ch.Detached = false + net.user.logger.Printf("network %q: attaching channel %q", net.GetName(), ch.Name) + detachedMsgID := ch.DetachedInternalMsgID + ch.Detached = false + ch.DetachedInternalMsgID = "" + var uch *upstreamChannel if net.conn != nil { uch = net.conn.channels.Value(ch.Name) @@ -276,12 +291,9 @@ func (net *network) attach(ch *Channel) { forwardChannel(dc, uch) } - lastDelivered := net.delivered.LoadID(ch.Name, dc.clientName) - if lastDelivered == "" { - return + if detachedMsgID != "" { + dc.sendTargetBacklog(net, ch.Name, detachedMsgID) } - - dc.sendTargetBacklog(net, ch.Name, lastDelivered) }) }