docs: Delete legacy presence subsystem page.

Everything on this page is now better explained in the API
documentation for presence.
This commit is contained in:
Tim Abbott
2025-06-19 14:40:39 -07:00
parent 01935c5be2
commit 8179a31dc7
8 changed files with 12 additions and 81 deletions

View File

@@ -34,7 +34,6 @@ django-upgrades
release-checklist
api-release-checklist
input-pills
presence
unread_messages
billing
widgets

View File

@@ -64,7 +64,7 @@ as follows:
if a user was present 1 minute before a message was sent, and then
closed their laptop, the user will not be in
`presence_idle_user_ids` (because it takes a
[few minutes](presence.md) of being idle for Zulip
[few minutes](https://zulip.com/api/update-presence) of being idle for Zulip
clients to declare to the server that the user is actually idle),
and so without an additional mechanism, messages sent shortly after
a user leaves would never trigger a notification (!).

View File

@@ -149,12 +149,12 @@ thousands of concurrent users.
`POST /users/me/presence` requests, which submit the current user's
presence information and return the information for all other active
users in the organization, account for about 36% of all HTTP requests
on production Zulip servers. See
[presence](presence.md) for details on this system and
how it's optimized. For this article, it's important to know that
presence is one of the most important scalability concerns for any
chat system, because it cannot be cached long, and is structurally a
quadratic problem.
on production Zulip servers. See the [presence API
documentation](https://zulip.com/api/update-presence) for details on
this system and how it's optimized. For this article, it's important
to know that presence is one of the most important scalability
concerns for any chat system, because it cannot be cached long, and is
structurally a quadratic problem.
Because typical presence requests consume 10-50ms of server-side
processing time (to fetch and send back live data on all other active

View File

@@ -1,52 +0,0 @@
# Presence
This document explains the model for Zulip's presence.
In a chat tool like Zulip, users expect to see the “presence” status
of other users: is the person I want to talk to currently online? If
not, were they last online 5 minutes ago, or more like an hour ago, or
a week? Presence helps set expectations for whether someone is likely
to respond soon. To a user, this feature can seem like a simple thing
that should be easy. But presence is actually one of the hardest
scalability problems for a team chat tool like Zulip.
There's a lot of performance-related details in the backend and
network protocol design that we won't get into here. The focus of
this is what one needs to know to correctly implement a Zulip client's
presence implementation (e.g., web app, mobile app, terminal client, or
other tool that's intended to represent whether a user is online and
using Zulip).
A client should report to the server every minute a `POST` request to
`/users/me/presence`, containing the current user's status. The
requests contains a few parameters. The most important is "status",
which had 2 valid values:
- "active" -- this means the user has interacted with the client
recently.
- "idle" -- the user has not interacted with the client recently.
This is important for the case where a user left a Zulip tab open on
their desktop at work and went home for the weekend.
The client receives in the response to that request a data set that,
for each user, contains their status and timestamp that we last heard
from that client. There are a few important details to understand
about that data structure:
- It's really important that the timestamp is the last time we heard
from the client. A client can only interpret the status to display
about another user by doing a simple computation using the (status,
timestamp) pair. E.g., a user who last used Zulip 1 week ago will
have a timestamp of 1 week ago and a status of "active". Why?
Because this correctly handles the race conditions. For example, if
the threshold for displaying a user as "offline" was 5 minutes
since the user was last online, the client can at any time
accurately compute whether that user is offline (even if the last
data from the server was 45 seconds ago, and the user was last
online 4:30 before the client received that server data).
- Users can disable their own presence updates in user settings
(`UserProfile.presence_enabled` is the flag storing [this user
preference](https://zulip.com/help/status-and-availability#disable-updating-availability)).
- The `status_from_timestamp` function in `web/src/presence.js` is
useful sample code; the `OFFLINE_THRESHOLD_SECS` check is critical
to correct output.

View File

@@ -30,8 +30,7 @@ def send_presence_changed(
# sends a message, recipients may still see that user as offline!
# We solve that by sending an immediate presence update clients.
#
# See https://zulip.readthedocs.io/en/latest/subsystems/presence.html for
# internals documentation on presence.
# The API documentation explains this interaction in more detail.
if settings.CAN_ACCESS_ALL_USERS_GROUP_LIMITS_PRESENCE:
user_ids = get_user_ids_who_can_access_user(user_profile)
else:

View File

@@ -14,9 +14,6 @@ class UserPresence(models.Model):
NOTE: Users can disable updates to this table (see UserProfile.presence_enabled),
so this cannot be used to determine if a user was recently active on Zulip.
The UserActivity table is recommended for that purpose.
This is a tricky subsystem, because it is highly optimized. See the docs:
https://zulip.readthedocs.io/en/latest/subsystems/presence.html
"""
user_profile = models.OneToOneField(UserProfile, on_delete=CASCADE, unique=True)

View File

@@ -10289,11 +10289,6 @@ paths:
Zulip clients like mobile/desktop apps will want to use the [main
presence endpoint](/api/get-presence), which returns data for all
active users in the organization, instead.
See [Zulip's developer documentation][subsystems-presence]
for details on the data model for presence in Zulip.
[subsystems-presence]: https://zulip.readthedocs.io/en/latest/subsystems/presence.html
parameters:
- name: user_id_or_email
in: path
@@ -10797,9 +10792,6 @@ paths:
use the modern [`last_update_id`](#parameter-last_update_id) protocol to
minimize fetching duplicate user presence data.
See [Zulip's developer documentation][subsystems-presence] for details
on the data model for user presence in Zulip.
The Zulip server is responsible for implementing [invisible mode][invisible],
which disables sharing a user's presence data. Nonetheless, clients
should check the `presence_enabled` field in user objects in order to
@@ -10811,7 +10803,6 @@ paths:
`true`, then user presence data in the response is [limited to users
the current user can see/access][limit-visibility].
[subsystems-presence]: https://zulip.readthedocs.io/en/latest/subsystems/presence.html
[limit-visibility]: /help/guest-users#configure-whether-guests-can-see-all-other-users
[invisible]: /help/status-and-availability#invisible-mode
[availability]: /help/status-and-availability#availability
@@ -12647,10 +12638,9 @@ paths:
setting is set to `true`, presence information of only accessible
users are returned.
See [Zulip's developer documentation][subsystems-presence]
for details on the data model for presence in Zulip.
[subsystems-presence]: https://zulip.readthedocs.io/en/latest/subsystems/presence.html
Complete Zulip apps are recommended to fetch presence
information when they post their own state using the [`POST
/presence`](/api/update-presence) API endpoint.
responses:
"200":
description: Success.

View File

@@ -574,9 +574,7 @@ STAGING = False
#
# The default for OFFLINE_THRESHOLD_SECS is chosen as
# `PRESENCE_PING_INTERVAL_SECS * 3 + 20`, which is designed to allow 2
# round trips, plus an extra in case an update fails. See
# https://zulip.readthedocs.io/en/latest/subsystems/presence.html for
# details on the presence architecture.
# round trips, plus an extra in case an update fails.
#
# How long to wait before clients should treat a user as offline.
OFFLINE_THRESHOLD_SECS = 200