This commit revises the code structure to share a single connection
to Redis (with multiple subscriptions on that connection) rather than
mutiple connections (each with one subscription). It also simplifies the code based on that change.
This commit implements a shared stream of data from Redis, which
allows all SSE connections that send the same data to the client
to share a single connection to Redis. (Previously, each client
got their own connection, which would significantly increase the
number of open Redis connections—especially since nearly all clients
will subscribe to `/public`.)
This commit tracks the number of active Pub/Sub streams and adds code to
keep the total number of streams below 400. (When additional users
attempt to connect past that point, the server will wait for an slot
to open up). This prevents "too many open file" panics and makes the
server better behaved in general. However, we may need to revisit it
based on what capacity we want the server to have.
This commit also includes some general refactoring.
This commit tracks the existence of the SSE stream and closes the
connection to the redis pub/sub channel when the stream is closed. This
prevents the number of redis connections from growing over time.
Note, however, that the current code still subscribes to one redis
channel per SSE connection rather than reusing existing subscriptions.
This will need to be fixed in a later PR.
This commit rolls up several days of work that took place in a side repo
which was originally intended to be a test/proof-of-concept repo but
that grew into a full implementation.
This implementation switches to Warp as the framework for the primary
web server (in large part because Warp offers built-in support for
SSE and several other advantages). This implementation relies on
a custom Redis interface built on Tokio (because the current Redis
Rust crate does not support asnyc PubSub). Using a custom interface
should also be faster, since it does not contain logic for anything
other than pubsub—which is all we need.
Finally, I note that the SSE support is currently as feature-complete
as it is possible to be without having yet added the Postgress interface
this means that all of the endpoints are present and are accessible
on localhost. However, none of the endpoints have authentication yet,
and the endpoints that should provide user-specific data (e.g.,
`/api/v1/streaming/user`) are currently hard-coded to provide data for
user 1 (the admin). Other than those limitations, however, the SSE
implementation is feature complete.
This commit removes the custom rustfmt rule (which specified a shorter
line length) so that the project conforms to idiomatic Rust formatting
standards.