fix: clean up leaked contexts on SSE disconnect and add orphan reaper

When clients disconnect without beforeunload firing (network drops,
mobile kills, crashes), contexts leaked in the registry permanently.

- Extract cleanupCtx helper for dispose/unregister sequence
- Call cleanupCtx on SSE disconnect (sse.Context().Done())
- Add background reaper for contexts where SSE never connected
- Add ContextTTL config option (default 30s, negative disables)
- Fix inverted condition in devModeRemovePersisted
This commit is contained in:
Ryan Hamamura
2026-02-06 10:34:28 -10:00
parent 2c44671d0e
commit 6dcd54c88b
4 changed files with 184 additions and 23 deletions

View File

@@ -8,6 +8,7 @@ import (
"maps"
"reflect"
"sync"
"sync/atomic"
"time"
"github.com/ryanhamamura/via/h"
@@ -33,6 +34,8 @@ type Context struct {
subscriptions []Subscription
subsMu sync.Mutex
disposeOnce sync.Once
createdAt time.Time
sseConnected atomic.Bool
}
// View defines the UI rendered by this context.
@@ -481,5 +484,6 @@ func newContext(id string, route string, v *V) *Context {
signals: new(sync.Map),
patchChan: make(chan patch, 1),
ctxDisposedChan: make(chan struct{}, 1),
createdAt: time.Now(),
}
}