For example, if I want to remove redundant messages from the queue - so that when actor recieves Connect message, it should inspect it's mailbox and remove other Connect messages, in order to do only one connect instead of several.
Is something like this possible?
Yes, you can configure the actors dispatcher to have any mailbox of your choice, so if you implement such a mailbox, you can use that, see the following section of the documentation: http://doc.akka.io/docs/akka/2.1.1/scala/dispatchers.html#Mailboxes
Related
The state of Reliable Actors including reminders are restored whenever a primary node fails. I could however not find any information regarding messages in the mailbox. What happens with these messages, are they lost or does the actor restore these messages?
The only information I could find is the following:
Because the actor service itself is a reliable service, all the
application model, lifecycle, packaging, deployment, upgrade, and
scaling concepts of Reliable Services apply the same way to actor
services.
I'm not sure if the above quote includes messages from a mailbox from an actor.
https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-actors-platform
SF Reliable Actors does not use the same mailbox messaging approach like Akka.
Akka uses the TELL approach where the messages are sent to the actor and stored in a mailbox for processing, once the processing is complete the actor send a message to the caller with an answer.
SF uses the ASK approach, where the caller keep waiting for the answer, so there is no mailbox, the processing will happens according to the locking order taken from the actor, if the actor service fails, the calls and locks will be dropped.
Because the calls and retries to the actors are managed by the caller, using the ActorProxy, it will resend the call, and it will get to a new service instance\replica, consequently getting a new priority order than before.
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.
Is there a way to drop a message on queue?
I receive my packet header and check some pattern on that, when that pattern fails I want to drop it. Is there a way for that? How to do that?
In rabbitMQ, messages are published on exchanges, and delivered to queues. You can configure a exchange that discards messages that fits some header patterns. Headers exchange. Or you can list a queue and ack a message that fits your pattern, without taking any further action, that is equivalent to drop message.
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.
Im using HornetQ as an embedded server. I am able to create multiple queues and have them bound to a single address. This works well and I can send a message to a single address and have it consumed by multiple queues. I've another business need to have multiple addresses sending messages to a single queue. The use case would be if you think of the queue as a user who is "subscribed" to multiple things happening in the system. Meaning that different events will post to different addresses and those messages will go to a users personal queue if he subscribed to them. Is this possible?
The only way I could think of it was to set up diverts. Wondering If there is a better way. Diverts work because I divert the messages on multiple addresses to a single unique address per user which maps to the queue. Btw; I'm using the CORE API
Wildcard queues?
http://docs.jboss.org/hornetq/2.2.5.Final/user-manual/en/html_single/index.html#wildcard-routing
Divert is a good option as well