fix: presence unreliable within same pod

It was broadcasting presence changes to other pods, but not notifying
clients connected to the same pod
This commit is contained in:
talksik
2026-04-12 09:58:41 -07:00
parent bb66bc4950
commit 1ffca8e239
+31
View File
@@ -101,6 +101,9 @@ func (h *Hub) handleSubscribe(ctx context.Context, req *subscribeRequest) {
h.channels[req.channelID] = ch
}
// Capture before addMember so multi-tab joins don't emit a spurious join.
wasPresentLocally := ch.hasHumanID(req.conn.humanID)
// Add to local channel
ch.addMember(req.conn, req.conn.humanID)
@@ -124,6 +127,16 @@ func (h *Hub) handleSubscribe(ctx context.Context, req *subscribeRequest) {
Channel: req.channelID,
Presence: presence,
})
// Notify other local members. The Redis self-filter drops our own echo,
// so same-pod peers would otherwise never hear about this join.
if !wasPresentLocally {
ch.broadcast(ServerMessage{
Type: TypeJoin,
Channel: req.channelID,
HumanID: req.conn.humanID,
}, req.conn)
}
}
func (h *Hub) handleUnsubscribe(ctx context.Context, req *unsubscribeRequest) {
@@ -144,6 +157,16 @@ func (h *Hub) handleUnsubscribe(ctx context.Context, req *unsubscribeRequest) {
slog.Error("redis unsubscribe failed", "channelId", req.channelID, "error", err)
}
// Notify other local members iff the humanID is fully gone from this pod
// (multi-tab: other conns keep them present, so no leave fires).
if !ch.hasHumanID(req.conn.humanID) {
ch.broadcast(ServerMessage{
Type: TypeLeave,
Channel: req.channelID,
HumanID: req.conn.humanID,
}, req.conn)
}
// Clean up empty local channel
if ch.isEmpty() {
delete(h.channels, req.channelID)
@@ -192,6 +215,14 @@ func (h *Hub) handleDisconnect(ctx context.Context, conn *Conn) {
slog.Error("redis unsubscribe on disconnect failed", "channelId", channelID, "error", err)
}
if !ch.hasHumanID(conn.humanID) {
ch.broadcast(ServerMessage{
Type: TypeLeave,
Channel: channelID,
HumanID: conn.humanID,
}, conn)
}
if ch.isEmpty() {
delete(h.channels, channelID)
}