rails
rails copied to clipboard
Add `:save_history` option to `stream_from`
Summary
This PR is an experiment motivated by this excellent RailsConf talk from @palkan, where he discusses message delivery guarantees in real-time Rails applications.
Since the beginning, ActionCable rely on Redis PubSub to create channels of communication between the server and the client. The purpose of a PubSub is solely to broadcast messages to multiple subscribers, not to make sure that they receive them. It means that if the network connection is lost for some reason, the subscriber will not be able to receive messages sent during their absence. If the subscriber is able to reconnect, they will have an inconsistent state if they don't refresh the page, thus killing the real-time experience.
To solve this problem we can use Redis PubSub in combination with Redis Streams. With Redis Streams, we can keep track of the messages sent by the server and retrieve the history when needed, using a timestamp that correspond to the last time the subscriber received a message from the server. This is easily achievable because Redis Streams uses timestamps as IDs.
The approach taken in this PR is to add a :save_history
option to stream_from
. This option takes a boolean or an hash with the following attributes:
-
:key
(Redis key of the stream history) -
:expires_after
(expiration time of the key)
If this option is enabled, subscribers will request the history of messages sent in their absence, after each reconnect:
Tasks
- [ ] Handling history expiration
- [ ] Writing tests
- [ ] Writing documentation