forked from MirrorHub/synapse
150 lines
6.7 KiB
ReStructuredText
150 lines
6.7 KiB
ReStructuredText
|
API Efficiency
|
||
|
==============
|
||
|
|
||
|
A simple implementation of presence messaging has the ability to cause a large
|
||
|
amount of Internet traffic relating to presence updates. In order to minimise
|
||
|
the impact of such a feature, the following observations can be made:
|
||
|
|
||
|
* There is no point in a Home Server polling status for peers in a user's
|
||
|
presence list if the user has no clients connected that care about it.
|
||
|
|
||
|
* It is highly likely that most presence subscriptions will be symmetric - a
|
||
|
given user watching another is likely to in turn be watched by that user.
|
||
|
|
||
|
* It is likely that most subscription pairings will be between users who share
|
||
|
at least one Room in common, and so their Home Servers are actively
|
||
|
exchanging message PDUs or transactions relating to that Room.
|
||
|
|
||
|
* Presence update messages do not need realtime guarantees. It is acceptable to
|
||
|
delay delivery of updates for some small amount of time (10 seconds to a
|
||
|
minute).
|
||
|
|
||
|
The general model of presence information is that of a HS registering its
|
||
|
interest in receiving presence status updates from other HSes, which then
|
||
|
promise to send them when required. Rather than actively polling for the
|
||
|
currentt state all the time, HSes can rely on their relative stability to only
|
||
|
push updates when required.
|
||
|
|
||
|
A Home Server should not rely on the longterm validity of this presence
|
||
|
information, however, as this would not cover such cases as a user's server
|
||
|
crashing and thus failing to inform their peers that users it used to host are
|
||
|
no longer available online. Therefore, each promise of future updates should
|
||
|
carry with a timeout value (whether explicit in the message, or implicit as some
|
||
|
defined default in the protocol), after which the receiving HS should consider
|
||
|
the information potentially stale and request it again.
|
||
|
|
||
|
However, because of the likelyhood that two home servers are exchanging messages
|
||
|
relating to chat traffic in a room common to both of them, the ongoing receipt
|
||
|
of these messages can be taken by each server as an implicit notification that
|
||
|
the sending server is still up and running, and therefore that no status changes
|
||
|
have happened; because if they had the server would have sent them. A second,
|
||
|
larger timeout should be applied to this implicit inference however, to protect
|
||
|
against implementation bugs or other reasons that the presence state cache may
|
||
|
become invalid; eventually the HS should re-enquire the current state of users
|
||
|
and update them with its own.
|
||
|
|
||
|
The following workflows can therefore be used to handle presence updates:
|
||
|
|
||
|
1 When a user first appears online their HS sends a message to each other HS
|
||
|
containing at least one user to be watched; each message carrying both a
|
||
|
notification of the sender's new online status, and a request to obtain and
|
||
|
watch the target users' presence information. This message implicitly
|
||
|
promises the sending HS will now push updates to the target HSes.
|
||
|
|
||
|
2 The target HSes then respond a single message each, containing the current
|
||
|
status of the requested user(s). These messages too implicitly promise the
|
||
|
target HSes will themselves push updates to the sending HS.
|
||
|
|
||
|
As these messages arrive at the sending user's HS they can be pushed to the
|
||
|
user's client(s), possibly batched again to ensure not too many small
|
||
|
messages which add extra protocol overheads.
|
||
|
|
||
|
At this point, all the user's clients now have the current presence status
|
||
|
information for this moment in time, and have promised to send each other
|
||
|
updates in future.
|
||
|
|
||
|
3 The HS maintains two watchdog timers per peer HS it is exchanging presence
|
||
|
information with. The first timer should have a relatively small expiry
|
||
|
(perhaps 1 minute), and the second timer should have a much longer time
|
||
|
(perhaps 1 hour).
|
||
|
|
||
|
4 Any time any kind of message is received from a peer HS, the short-term
|
||
|
presence timer associated with it is reset.
|
||
|
|
||
|
5 Whenever either of these timers expires, an HS should push a status reminder
|
||
|
to the target HS whose timer has now expired, and request again from that
|
||
|
server the status of the subscribed users.
|
||
|
|
||
|
6 On receipt of one of these presence status reminders, an HS can reset both
|
||
|
of its presence watchdog timers.
|
||
|
|
||
|
To avoid bursts of traffic, implementations should attempt to stagger the expiry
|
||
|
of the longer-term watchdog timers for different peer HSes.
|
||
|
|
||
|
When individual users actively change their status (either by explicit requests
|
||
|
from clients, or inferred changes due to idle timers or client timeouts), the HS
|
||
|
should batch up any status changes for some reasonable amount of time (10
|
||
|
seconds to a minute). This allows for reduced protocol overheads in the case of
|
||
|
multiple messages needing to be sent to the same peer HS; as is the likely
|
||
|
scenario in many cases, such as a given human user having multiple user
|
||
|
accounts.
|
||
|
|
||
|
|
||
|
API Requirements
|
||
|
================
|
||
|
|
||
|
The data model presented here puts the following requirements on the APIs:
|
||
|
|
||
|
Client-Server
|
||
|
-------------
|
||
|
|
||
|
Requests that a client can make to its Home Server
|
||
|
|
||
|
* get/set current presence state
|
||
|
Basic enumeration + ability to set a custom piece of text
|
||
|
|
||
|
* report per-device idle time
|
||
|
After some (configurable?) idle time the device should send a single message
|
||
|
to set the idle duration. The HS can then infer a "start of idle" instant and
|
||
|
use that to keep the device idleness up to date. At some later point the
|
||
|
device can cancel this idleness.
|
||
|
|
||
|
* report per-device type
|
||
|
Inform the server that this device is a "mobile" device, or perhaps some
|
||
|
other to-be-defined category of reduced capability that could be presented to
|
||
|
other users.
|
||
|
|
||
|
* start/stop presence polling for my presence list
|
||
|
It is likely that these messages could be implicitly inferred by other
|
||
|
messages, though having explicit control is always useful.
|
||
|
|
||
|
* get my presence list
|
||
|
[implicit poll start?]
|
||
|
It is possible that the HS doesn't yet have current presence information when
|
||
|
the client requests this. There should be a "don't know" type too.
|
||
|
|
||
|
* add/remove a user to my presence list
|
||
|
|
||
|
Server-Server
|
||
|
-------------
|
||
|
|
||
|
Requests that Home Servers make to others
|
||
|
|
||
|
* request permission to add a user to presence list
|
||
|
|
||
|
* allow/deny a request to add to a presence list
|
||
|
|
||
|
* perform a combined presence state push and subscription request
|
||
|
For each sending user ID, the message contains their new status.
|
||
|
For each receiving user ID, the message should contain an indication on
|
||
|
whether the sending server is also interested in receiving status from that
|
||
|
user; either as an immediate update response now, or as a promise to send
|
||
|
future updates.
|
||
|
|
||
|
Server to Client
|
||
|
----------------
|
||
|
|
||
|
[[TODO(paul): There also needs to be some way for a user's HS to push status
|
||
|
updates of the presence list to clients, but the general server-client event
|
||
|
model currently lacks a space to do that.]]
|