AKKA FSM : Messages are not delivered to FSM actor references properly - scala

I've a very strange problem with AKKA FSM.
I've a pool of fsm actor references created at the time of app initialization and the requirement is to send incoming streams of messages to all those actors references, so unfortunately some of the messages are not being sent properly.
Is there a mechanism to track the messages are delivered or not, Please let me know if anybody encountered/solved these.
Appreciate your help!
Thanks,
~Shiva

Checkout the FSM Documentation, specifically the section on Testing and Debugging Finite State Machines. In a nutshell, you need to:
Wrap your receive in a LoggingFSM
Make sure to set the config setting akka.actor.debug.fsm to true
Make sure your logging level is set to DEBUG,
If you do all of that you should start seeing debug level messages related to events/state transitions/timers for your FSM actors.

Related

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.

How to recover messages in Akka Actors now that Durable Mailboxes are removed?

I was working with the latest version of Akka when I noticed that durable mailboxes are now removed from Akka.
I need to make sure that my messages are recovered upon a restart after crash. Is there an alternate way to work without durable mailboxes or a custom implementation by someone else.
I also tried Akka Persistence but it replays the messages and I don't want to send the same messages twice in the event of a crash given that all messages are expensive to perform.
While this is not exactly a solution to work with Akka Actors, it does solve the original problem in question here.
Instead of using Akka here, I believe it's a better idea to use something like Kafka along with reactive streams with something like akka/reactive-kafka.
A system like that is very good for persistence, and offers very good semantics for preserving the message queue on a crash. This is way better than storing the message somewhere that is to be processed, and in general performs better.
It does not have to be Kafka, but any backend that can plug with a reactive stream (Akka's implementation or otherwise).
Akka Persistence replays events that were created based on received commands. Events are generated from command messages after validation and shouldn't be able to create invalid actor states.
This means that not the initial received messages (commands) are necesarilly replayed but you can persist events that are cheaper to apply to reconstruct the state of an actor after the crash. In addition you can use snapshots to recover state directly.
Edit:
As mentioned i the comments it is true that only the state of the actor is persisted and survives the crash. This state only reflects the consumed messages and not those that still reside in the actors mailbox.
However instead of pushing messages to an actor which would then be stored in a durable mailbox an alternative might be for the 'recipient' to pull messages from a persistent actor which stores the list of messages as part of his state.
UntypedPersistentActorWithAtLeastOnceDelivery as part of akka persistence offers another possibility where the sender takes care of persisting messages.
I realize that those are no drop-in replacements for durable mailboxes as they require rethinking the system. Pulling work from the consumers has worked for me so far. Initially we also considered message Queue products (RabbitMQ with durable queues) but since our initial work items come from a db we can deal with an akka crash without durable messages.

Akka test for deadletters

How can I make assertion against deadletters in Akka while testing?
I have an actor which can switch behaviours (using become) and deals with some Futures dispatched using separate Dispatcher. In some certain condition it should simply reject other messages.
Those correctly go to a deadletters, however I would like to try to assert for them (or lack of). How can I do this?
Dead letters are delivered using the event stream so you can subscribe to that in your tests with a probe and verify messages or lack of messages
system.eventStream.subscribe(probe, classOf[DeadLetter])

Scalatra, Atmosphere, and Receiving Multiple Messages

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.

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.