rails icon indicating copy to clipboard operation
rails copied to clipboard

Add `:save_history` option to `stream_from`

Open mansakondo opened this issue 1 year ago • 0 comments

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: streams_history

Tasks

  • [ ] Handling history expiration
  • [ ] Writing tests
  • [ ] Writing documentation

mansakondo avatar Aug 05 '22 01:08 mansakondo