This commit adds the concept of eyes. One "eyes" is one instance of a
response to GET /stream.mp4. Currently the number of eyes clients can
have is unbounded, but this is a DoS vector.
Client and server both close the connection if they don't hear from the
other party after a timeout period. This is a failsafe and should
improve reliability.
This adds a field 'watching' in `user_for_websocket` that's True iff WATCHING,
False iff NOTWATCHING, and None otherwise (since clients don't need to know if
a user is tentative or absent). When the value of this field changes for any
user, they get added to the update buffer (like with any other change).
Removed race condition in `t_sunset_users`: `broadcast_users_update` was being
called *after* a user was removed from memory (and for each user being removed,
which was redundant). In that scenario if there's a user in the update buffer
and `t_sunset_users` wins the race between it and `t_broadcast_users_update`,
then when `t_sunset_users` calls `broadcast_users_update` a KeyError would be
raised since the user's already been removed.
Fixed unintended behaviour of `t_sunset_users`: it was removing users based on
the result of `is_visible`, so users who were actually tenative (as opposed to
absent) were being removed.
Incoming requests are handled in anonstream/routes/. Route handlers
mainly depend on files in anonstream/, which in turn depend on files in
anonstream/helpers/ and anonstream/utils/. Utils are pure functions and
helpers are almost pure functions; they don't mutate state but they
do depend on the global app config.