Files
ntfy/server/stream_registry.go
T
binwiederhier 62fb43b44b Make the cluster the owner of maintenance mode
The cluster now owns the maintenance state (Cluster.Maintenance) instead of the server keeping its own copy; the server keeps only the draining phase. Role() returns the role the node acts in (passive in maintenance mode), so /v1/ready says "role":"passive","maintenance":true. Cluster.HasActivePeer replaces the server's own walk over Members. A single-node server no longer logs about maintenance mode on every shutdown. The stream registry moves to its own file, with unit tests.
2026-10-23 19:42:18 +00:00

62 lines
1.5 KiB
Go

package server
import (
"context"
"sync"
)
// streamRegistry tracks the open subscriber connections (HTTP streams and WebSockets), one entry
// per connection however many topics it subscribes to, so a drain can close them one at a time.
// Polls are not streams: they end on their own.
type streamRegistry struct {
nextID int
cancels map[int]context.CancelFunc
mu sync.Mutex // Protects nextID and cancels
}
func newStreamRegistry() *streamRegistry {
return &streamRegistry{
cancels: make(map[int]context.CancelFunc),
}
}
// Add registers a stream and returns its ID for Remove
func (r *streamRegistry) Add(cancel context.CancelFunc) int {
r.mu.Lock()
defer r.mu.Unlock()
r.nextID++
r.cancels[r.nextID] = cancel
return r.nextID
}
// Remove forgets a stream that ended; a stream CancelSome already closed is gone already
func (r *streamRegistry) Remove(id int) {
r.mu.Lock()
defer r.mu.Unlock()
delete(r.cancels, id)
}
// Len returns the number of open streams
func (r *streamRegistry) Len() int {
r.mu.Lock()
defer r.mu.Unlock()
return len(r.cancels)
}
// CancelSome closes up to n streams, picked in map order (i.e. at random), and returns how
// many it closed. They are removed right away, so the next call picks others.
func (r *streamRegistry) CancelSome(n int) int {
r.mu.Lock()
defer r.mu.Unlock()
canceled := 0
for id, cancel := range r.cancels {
if canceled >= n {
break
}
cancel()
delete(r.cancels, id)
canceled++
}
return canceled
}