feat(presence): add distributed presence service for the social layer#5
Merged
Conversation
Introduce a standalone Presence Service as the foundation for friends,
parties, invites, reconnect and notifications. Presence is modeled as a
distributed system, not an online/offline boolean.
Design:
- Redis is the source of truth: presence:{id} JSON (state, last_seen,
connection_count) with a TTL. WS replicas heartbeat every 15s to refresh a
45s TTL, so presence self-heals after crashes/partitions with no explicit
disconnect — a missing key is OFFLINE.
- All mutations are Lua scripts (atomic read-modify-write), so any WS replica
can update any player with no sticky sessions and no leader election —
horizontally scalable.
- Multi-device: connection_count keeps a player ONLINE until the last
connection closes.
- States OFFLINE/ONLINE/IN_QUEUE/IN_MATCH/AWAY with a deliberately permissive
transition rule (only OFFLINE->IN_QUEUE/IN_MATCH rejected) so future
reconnect/rematch/party flows need no state-machine changes.
- Publishes PresenceOnline/Offline/StateChanged to NATS (events.presence,
15m retention) via the shared events.Publisher with trace propagation;
consumers are optional. Reads are side-effect free.
- Bulk friend lookup (POST /presence/friends) via a single Redis pipeline:
O(N) commands, one round trip, no N+1.
WS gateway feeds presence over HTTP through an injected, optional notifier
(nil = no-op) — the only coupling, no WS internals touched. Adds metrics,
tracing spans, k8s manifest (2 replicas), Dockerfile, compose, and
docs/presence.md. matchmaking is unchanged.
Unexport the Repository mutating methods (connect/disconnect/heartbeat/ setState) so they no longer return the package-private mutation type through an exported API; only Service calls them in-package. Add doc comments to the State const block and the HTTPNotifier/NoopNotifier methods.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Introduce a standalone Presence Service as the foundation for friends, parties, invites, reconnect and notifications. Presence is modeled as a distributed system, not an online/offline boolean.
Design:
WS gateway feeds presence over HTTP through an injected, optional notifier (nil = no-op) — the only coupling, no WS internals touched. Adds metrics, tracing spans, k8s manifest (2 replicas), Dockerfile, compose, and docs/presence.md. matchmaking is unchanged.