diff --git a/docs/subsystems/index.md b/docs/subsystems/index.md index 63012daaaf..4c6fab50bb 100644 --- a/docs/subsystems/index.md +++ b/docs/subsystems/index.md @@ -34,7 +34,6 @@ django-upgrades release-checklist api-release-checklist input-pills -presence unread_messages billing widgets diff --git a/docs/subsystems/notifications.md b/docs/subsystems/notifications.md index 77e3f0a110..2d856cdced 100644 --- a/docs/subsystems/notifications.md +++ b/docs/subsystems/notifications.md @@ -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 (!). diff --git a/docs/subsystems/performance.md b/docs/subsystems/performance.md index 37e311edf6..016e532d41 100644 --- a/docs/subsystems/performance.md +++ b/docs/subsystems/performance.md @@ -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 diff --git a/docs/subsystems/presence.md b/docs/subsystems/presence.md deleted file mode 100644 index c311009a78..0000000000 --- a/docs/subsystems/presence.md +++ /dev/null @@ -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. diff --git a/zerver/actions/presence.py b/zerver/actions/presence.py index 16e6b33511..1c90f6ddc8 100644 --- a/zerver/actions/presence.py +++ b/zerver/actions/presence.py @@ -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: diff --git a/zerver/models/presence.py b/zerver/models/presence.py index ff419b0bc2..d77621733e 100644 --- a/zerver/models/presence.py +++ b/zerver/models/presence.py @@ -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) diff --git a/zerver/openapi/zulip.yaml b/zerver/openapi/zulip.yaml index 1ad1ef8ce7..6df3ce4f23 100644 --- a/zerver/openapi/zulip.yaml +++ b/zerver/openapi/zulip.yaml @@ -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. diff --git a/zproject/default_settings.py b/zproject/default_settings.py index bc330d67aa..61bf1b3ad7 100644 --- a/zproject/default_settings.py +++ b/zproject/default_settings.py @@ -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