From 46f28203edad9b6164d88fd666e1a7eb2e01d5dc Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Wed, 1 Oct 2025 12:08:08 -0300 Subject: [PATCH] khatru: expiration manager takes query and delete methods, which are given automatically by .UseEventstore() --- khatru/expiration.go | 69 +++++++++++++++++++++++++++++--------------- khatru/relay.go | 23 +-------------- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/khatru/expiration.go b/khatru/expiration.go index 89f6b80..0bd3983 100644 --- a/khatru/expiration.go +++ b/khatru/expiration.go @@ -3,6 +3,8 @@ package khatru import ( "container/heap" "context" + "iter" + "slices" "sync" "time" @@ -34,25 +36,18 @@ func (h *expiringEventHeap) Pop() interface{} { } type expirationManager struct { - events expiringEventHeap - mu sync.Mutex - relay *Relay + events expiringEventHeap + mu sync.Mutex + + queryStored func(ctx context.Context, filter nostr.Filter) iter.Seq[nostr.Event] + deleteEvent func(ctx context.Context, id nostr.ID) error + interval time.Duration initialScanDone bool kill chan struct{} // used for manually killing this killonce *sync.Once } -func newExpirationManager(relay *Relay) *expirationManager { - return &expirationManager{ - events: make(expiringEventHeap, 0), - relay: relay, - interval: time.Hour, - kill: make(chan struct{}), - killonce: &sync.Once{}, - } -} - func (em *expirationManager) stop() { em.killonce.Do(func() { close(em.kill) @@ -86,14 +81,12 @@ func (em *expirationManager) initialScan(ctx context.Context) { // query all events ctx = context.WithValue(ctx, internalCallKey, struct{}{}) - if nil != em.relay.QueryStored { - for evt := range em.relay.QueryStored(ctx, nostr.Filter{}) { - if expiresAt := nip40.GetExpiration(evt.Tags); expiresAt != -1 { - heap.Push(&em.events, expiringEvent{ - id: evt.ID, - expiresAt: expiresAt, - }) - } + for evt := range em.queryStored(ctx, nostr.Filter{}) { + if expiresAt := nip40.GetExpiration(evt.Tags); expiresAt != -1 { + heap.Push(&em.events, expiringEvent{ + id: evt.ID, + expiresAt: expiresAt, + }) } } @@ -116,9 +109,7 @@ func (em *expirationManager) checkExpiredEvents(ctx context.Context) { heap.Pop(&em.events) ctx := context.WithValue(ctx, internalCallKey, struct{}{}) - if nil != em.relay.DeleteEvent { - em.relay.DeleteEvent(ctx, next.id) - } + em.deleteEvent(ctx, next.id) } } @@ -145,3 +136,33 @@ func (em *expirationManager) removeEvent(id nostr.ID) { } } } + +func (rl *Relay) StartExpirationManager( + queryStored func(ctx context.Context, filter nostr.Filter) iter.Seq[nostr.Event], + deleteEvent func(ctx context.Context, id nostr.ID) error, +) { + rl.expirationManager = &expirationManager{ + events: make(expiringEventHeap, 0), + + queryStored: queryStored, + deleteEvent: deleteEvent, + + interval: time.Hour, + kill: make(chan struct{}), + killonce: &sync.Once{}, + } + + go rl.expirationManager.start(rl.ctx) + rl.Info.AddSupportedNIP(40) +} + +func (rl *Relay) DisableExpirationManager() { + rl.expirationManager.stop() + rl.expirationManager = nil + + idx := slices.Index(rl.Info.SupportedNIPs, 40) + if idx != -1 { + rl.Info.SupportedNIPs[idx] = rl.Info.SupportedNIPs[len(rl.Info.SupportedNIPs)-1] + rl.Info.SupportedNIPs = rl.Info.SupportedNIPs[0 : len(rl.Info.SupportedNIPs)-1] + } +} diff --git a/khatru/relay.go b/khatru/relay.go index 5ee7568..dcc138d 100644 --- a/khatru/relay.go +++ b/khatru/relay.go @@ -6,7 +6,6 @@ import ( "log" "net/http" "os" - "slices" "strconv" "strings" "sync" @@ -53,8 +52,6 @@ func NewRelay() *Relay { MaxAuthenticatedClients: 32, } - rl.expirationManager = newExpirationManager(rl) - return rl } @@ -152,7 +149,7 @@ func (rl *Relay) UseEventstore(store eventstore.Store, maxQueryLimit int) { } // only when using the eventstore we automatically set up the expiration manager - rl.StartExpirationManager() + rl.StartExpirationManager(rl.QueryStored, rl.DeleteEvent) } func (rl *Relay) getBaseURL(r *http.Request) string { @@ -180,21 +177,3 @@ func (rl *Relay) getBaseURL(r *http.Request) string { } return proto + "://" + host } - -func (rl *Relay) StartExpirationManager() { - if rl.expirationManager != nil { - go rl.expirationManager.start(rl.ctx) - rl.Info.AddSupportedNIP(40) - } -} - -func (rl *Relay) DisableExpirationManager() { - rl.expirationManager.stop() - rl.expirationManager = nil - - idx := slices.Index(rl.Info.SupportedNIPs, 40) - if idx != -1 { - rl.Info.SupportedNIPs[idx] = rl.Info.SupportedNIPs[len(rl.Info.SupportedNIPs)-1] - rl.Info.SupportedNIPs = rl.Info.SupportedNIPs[0 : len(rl.Info.SupportedNIPs)-1] - } -}