Question

I'm planning to reengineer an existing system to use Akka, Play and Websockets.

My current system is based on Jetty and Websockets.

I've a fast stream of messages that are published into a Redis channel. In my web app layer I subscribe to these messages using a Jedis subscriber and then push those messages to a Websocket which are then displayed on a browser.

I want to make the shift two two primary reason - a) better and simpler fault tolerance due to use of Actors b) the ability to connect to multiple streams using different actors

In my current design I've a supervisor that creates a new child actor for every new channel. The child actor then subscribes to a Redis channel. My question what's the best way to push the messages (received from the Redis channel) to a Play Websocket ?

Was it helpful?

Solution

I'd start with a solution based on three layers of Actors. From Redis feed to Websockets:

  • ChannelDispatcherActor
  • ChannelActor
  • WebsocketActor

ChannelDispatcherActor is a singleton that receives a stream of Publish(Channel, Content) from the Redis feed, and maintains a private map of Channel to ChannelActor with lazy-create semantics. It accepts messages

  • Subscribe(Channel, WebsocketActor) - lookup ChannelActor for Channel, create if necessary, forward to ChannelActor
  • Unsubscribe(Channel, WebsocketActor) - same - lookup & forward
  • Publish(Channel, Content) - same - lookup & forward

ChannelActor is one-per-Channel and maintains a set of WebsocketActors listening to its channel. It accepts messages

  • Subscribe(Channel, WebsocketActor) - add WebsocketActor to listeners, also context.watch(actorref)
  • Unsubscribe(Channel, WebsocketActor) - remove from listeners
  • Terminated(WebsocketActor) - remove from listeners
  • Publish() - send to each in listeners

WebsocketActor is one-per-websocket and maintains a list of Channels a websocket is subscribed to, and publishes traffic it receives from ChannelActors to its websocket. To manage to a Channels it sends ChannelDispatcherActor Subscribe/Unsubscribes. It terminates itself when the websocket is closed, and WebsocketActors cleanup their listener lists through then watch()es.

Lots of optimizations to be made, and this does nothing for fault tolerance, but those are separate posts.

Happy hakking !!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top