Presence & status model + endpoints (Redis heartbeat) #24
@@ -43,7 +43,7 @@ class PresenceResponse(BaseModel):
|
||||
|
||||
|
||||
class StatusUpdate(BaseModel):
|
||||
status_message: str | Field(default=None, max_length=_STATUS_MAX_LEN)
|
||||
status_message: str | None = Field(default=None, max_length=_STATUS_MAX_LEN)
|
||||
|
||||
@field_validator("status_message")
|
||||
@classmethod
|
||||
@@ -107,7 +107,7 @@ async def get_presence(
|
||||
)
|
||||
|
||||
# Check Redis for online status
|
||||
online_ids = await _presence_store.is_online(ids)
|
||||
online_ids = await _presence_store.is_online_batch(ids)
|
||||
|
||||
# Fetch DB records for last_seen_at and status_message
|
||||
result = await db.execute(
|
||||
|
||||
@@ -95,6 +95,16 @@ class PresenceStore:
|
||||
exists = await self.client.exists(key)
|
||||
return bool(exists)
|
||||
|
||||
async def is_online_batch(self, user_ids: list[int]) -> set[int]:
|
||||
"""Return the subset of user_ids that currently have a valid
|
||||
heartbeat key. Uses MGET (one round trip) rather than one EXISTS
|
||||
per user."""
|
||||
if not user_ids:
|
||||
return set()
|
||||
keys = [self._heartbeat_key(uid) for uid in user_ids]
|
||||
values = await self.client.mget(keys)
|
||||
return {uid for uid, v in zip(user_ids, values) if v is not None}
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Presence lookup
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user