KamoCRM

Presence bulk reads and the stale-presence sweep stop using Redis KEYS

FixMediaService
Shipped
September 23, 2026 at 10:41 AM UTC
Author
Kamo
Commit
e696226

getBulkPresence/getBulkLastSeen ran KEYS PRESENCE:*/PRESENCE_LAST_SEEN:* on every call - hit on every presence-socket mount and tab focus - and the 30s sweep ran it twice more, all against the same Redis that holds every *** session. KEYS walks and blocks the entire keyspace; at platform scale that is a full-Redis stall on a request path, not a per-org one. Each of the three now reads a maintained index instead of scanning: - PRESENCE_ORG_INDEX:{orgId} - a ZSET of memberId scored by last heartbeat, written by handleConnect/handleHeartbeat, removed by handleDisconnect's grace-period delete. getBulkPresence reads it directly (org scoping is by construction now, not a per-candidate orgId check); the sweep's member half reads it with ZRANGEBYSCORE to find only plausibly-stale candidates. - PRESENCE_ACTIVE_ORGS - a SET of org ids, so the sweep can visit every org's index without discovering org ids by scanning member data. - **************** - a SET backing getBulkLastSeen the same way. Not swept, same as before: the individual key's own 400-day TTL is still what retires it. - PRESENCE_PUBLIC_INDEX - one flat ZSET for visitor sessions (no org concept, nothing reads them in bulk by org), feeding the sweep's public half. Every per-id hash key (PRESENCE:, PRESENCE_PUBLIC:, PRESENCE_LAST_SEEN:) is unchanged - same fields, same TTLs - and stays the single source of truth for its own state; an index only narrows which ids get looked at; a read or the sweep still checks the real hash before trusting or reporting anything, and self-heals (drops the index entry) if the hash has already outlived it. A revived heartbeat (key expired mid-session) still cannot attribute an org - the same gap the old KEYS+HGET("orgId") scan had, since that path never wrote the field either; only the org-bulk view is affected, unchanged from before. Covered by PresenceBulkLookupTest (new) and PresenceSweepTest (rewritten for the new discovery mechanism, same behavioural pins as before plus a "never calls KEYS" check), mutation-checked: dropping the index write in handleConnect, the self-heal branch in getBulkPresence, and the hasKey guard in the sweep each turn a specific assertion red.

All changes

Like what you see shipping?

All of it arrives in your workspace on its own. Start on the free plan and read this page again in a month.

Start Free ForeverView Pricing