From bba70d0a2903ab1fff5a2e89cff97cb1f6c7f82a Mon Sep 17 00:00:00 2001 From: Jeff Halter <868228+jhalter@users.noreply.github.com> Date: Thu, 25 Jun 2026 07:44:23 -0700 Subject: Introduce PresenceTracker interface for online-user tracking Replace the leaky *redis.Client field on Server with a PresenceTracker interface that receives connect/rename/disconnect lifecycle events. This removes Redis-specific set encoding from hotline/server.go and the session handlers, and drops the redis dependency from the hotline package. The Redis implementation moves to mobius.RedisPresenceTracker, which owns the legacy "login::ip"/"login:nickname:ip" set encoding so existing deployments keep working. The API server reads online users through a new OnlineLister interface and falls back to the in-memory ClientMgr when no presence tracker is configured. Startup clearing of stale online state now happens unconditionally when Redis is configured, not only when the API server is enabled. --- cmd/mobius-hotline-server/main.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'cmd/mobius-hotline-server/main.go') diff --git a/cmd/mobius-hotline-server/main.go b/cmd/mobius-hotline-server/main.go index ba7924d..5191805 100644 --- a/cmd/mobius-hotline-server/main.go +++ b/cmd/mobius-hotline-server/main.go @@ -122,6 +122,7 @@ func main() { reloaders = append(reloaders, namedReloader{"message board", messageBoard}) // Initialize ban list - use Redis if configured, otherwise use file-based storage + var onlineLister mobius.OnlineLister if *redisAddr != "" { redisClient := redis.NewClient(&redis.Options{ Addr: *redisAddr, @@ -135,7 +136,14 @@ func main() { os.Exit(1) } - srv.Redis = redisClient + presence := mobius.NewRedisPresenceTracker(redisClient, slogger) + // Discard stale online state from a previous run. + if err := presence.Clear(ctx); err != nil { + slogger.Warn("Failed to clear online users in Redis", "err", err) + } + srv.Presence = presence + onlineLister = presence + srv.BanList = mobius.NewRedisBanMgr(redisClient, slogger) slogger.Debug("Using Redis for ban management", "addr", *redisAddr) } else { @@ -195,7 +203,7 @@ func main() { } if *apiAddr != "" { - sh := mobius.NewAPIServer(srv, reloadFunc, slogger, *apiKey) + sh := mobius.NewAPIServer(srv, onlineLister, reloadFunc, slogger, *apiKey) go sh.Serve(*apiAddr) } -- cgit