Scalatra, Atmosphere, and Receiving Multiple Messages - scala

I am just playing with Scalatra and Akka like the guide suggests http://www.scalatra.org/guides/async/atmosphere.html. I've modified the guid so that I'm passing an actor system into the Atmosphere client.
However, I would like to know how I can get messages from the actor system back down to the client.
I can't use the ask pattern because the actor system may send multiple messages to the client - not one. What should I do here?

Perhaps you can use The Inbox.

Related

akka remote actors - do the sender and receiver actors have to be on the same project?

I was following the akka-in-action code-base remoting (https://github.com/RayRoestenburg/akka-in-action/tree/master/chapter-remoting). In the example, it explains remoting with sender actor and a receiver actor. Both the actors are started separately (via separate Main) and they are able to communicate as explained (Note:- both the actors are part of same code base).
I wanted to see how it behaves if the sender actor is part of a different project(independent code base). I created a Play web-app which sends a message to the above mentioned receiver actor upon getting a POST call thru some rest client (I used Postman).
What I observed is that, even though the message sent (a Case Class) is available in both the sender and receiver code base, the receiver complains a class not found error (its not able to understand the Case Class object that I sent from sender)
Is it an expected behavior that, if remoting has to work, the distributed actors should share same code-base?
Moving to Kryo/Chill will partially solve your problem, as long as you use the same exact version of Akka underneath. These binary serialization formats are inherently fragile. Avro does a better job at solving lifecycle issues of binary serialization; but alas, I have never seen Avro used as for serialization in Akka.

Moving from socko to akka-http websockets

I have an existing akka application built on socko websockets. Communication with the sockets takes place inside a single actor and messages both leaving and entering the actor (incoming and outgoing messages, respectively) are labelled with the socket id, which is a first class property of a socko websocket (in socko a connection request arrives labelled with the id, and all the lifecycle transitions such as handshaking, disconnection, incoming frames etc. are similarly labelled)
I'd like to reimplement this single actor using akka-http (socko is more-or-less abandonware these days, for obvious reasons) but it's not straightforward because the two libraries are conceptually very different; akka-http hides the lower level details of the handshaking, disconnection etc, simply sending whichever actor was bound to the http server an UpgradeToWebsocket request header. The header object contains a method that takes a materialized Flow as a handler for all messages exchanged with the client.
So far, so good; I am able to receive messages on the web socket and reply them directly. The official examples all assume some kind of stateless request-reply model, so I'm struggling with understanding how to make the next step to assigning a label to the materialized flow, managing its lifecycle and connection state (I need to inform other actors in the application when a connection is dropped by a client, as well as label the messages.)
The alternative (remodelling the whole application using akka-streams) is far too big a job, so any advice about how to keep track of the sockets would be much appreciated.
To interface with an existing actor-based system, you should look at Source.actorRef and Sink.actorRef. Source.actorRef creates an ActorRef that you can send messages to, and Sink.actorRef allows you to process the incoming messages using an actor and also to detect closing of the websocket.
To connect the actor created by Source.actorRef to the existing long-lived actor, use Flow#mapMaterializedValue. This would also be a good place to assign an unique id for a socket connection.
This answer to a related question might get you started.
One thing to be aware of. The current websocket implementation does not close the server to client flow when the client to server flow is closed using a websocket close message. There is an issue open to implement this, but until it is implemented you have to do this yourself. For example by having something like this in your protocol stack.
The answer from RĂ¼diger Klaehn was a useful starting point, thanks!
In the end I went with ActorPublisher after reading another question here (Pushing messages via web sockets with akka http).
The key thing is that the Flow is 'materialized' somewhere under the hood of akka-http, so you need to pass into UpgradeToWebSocket.handleMessagesWithSinkSource a Source/Sink pair that already know about an existing actor. So I create an actor (which implements ActorPublisher[TextMessage.Strict]) and then wrap it in Source.fromPublisher(ActorPublisher(myActor)).
When you want to inject a message into the stream from the actor's receive method you first check if totalDemand > 0 (i.e. the stream is willing to accept input) and if so, call onNext with the contents of the message.

Scalatra, Atmosphere, and sending messages to clients from outside the message handler

I'm currently reading through the official Scalatra documentation, particularly the guide on using Scalatra with Atmosphere. That page explains how to use Scalatra and Atmosphere to write a WebSocket based application which responds to incoming messages with outgoing messages.
For the purposes of an application which connects multiple different messaging sources, how would I send outgoing messages from elsewhere in the application?
Possible examples include:
messages sent as a result of an incoming HTTP request
periodic messages on a timer
messages pulled from a queue
etc.
Some of these messages could potentially target multiple clients.
I'm a bit confused by the official docs on this matter because all the examples happen various incoming message handlers and I'm not sure where to get a reference to the Atmosphere system or where/how I'm allowed to call it.
I Hope someone can clarify.

how is it possible to use spray and akka without blocking until result is estimated?

This question is more about architecture than anything else.
I just started building a Rest API with akka. Currently I use play for doing the necessary routing. The problem with play is that I have my entry point for akka within my controller, so there is always one actor that has to wait all the time until my business logic calculates a suitable response.
Now I came across spray and it looks like there is nearly the same problem with it. (spray-routing)
What I`m trying to achieve is that I have an entry point that receives a HTTPRequest, then the request is handled by my actor system and at the end of this system there is an actor which sends the priviously calculated response back to the requesting client.
Actually I cant figure out how to chain actors without waiting for an end result. What I want is a "START" - Actor receiving a Request and one at the end sending back the response.
I hope i wrote it so that someone understands what I mean.
Thanks in advance.

How does Play recognize a particular websocket message?

I am looking at the websocket-chat example. It unveils much, but I still cannot get something. I understand how messages are received, processed and sent on the web page side.
However, Play captures websocket messages by means of the receive method of an Akka actor. In the websocket-chat, there are several cases in this method, but I don't get, how does it know which websocket message should be mapped to which case. In fact, I don't understand the path that a websocket message follows upon entering Play's domain, how is it processed and how can different message types/kinds be sent from the webpage.
I have not find any info or sources related to this. Could please someone explain this or point to some kind of a good reference?
UPDATE:
The link to the original example.
The receive method from the sample doesn't have any link to the Play Websocket API. This receive method comes from the Akka library.
The Websockets events are managed through an Iteratee, which create and send a Talk message to the Actor system.
Simply put, it allows to have a highly scalable system (non-blocking), by sending messages between "workers".
So I suggest that you take a look at the Actor model in the Akka library.