Is this a valid use case for "ask" with regard to akka? - scala

I'm reading http://danielwestheide.com/blog/2013/02/27/the-neophytes-guide-to-scala-part-14-the-actor-approach-to-concurrency.html and in it, is declared :
"Sometimes, sending an actor a message and expecting a message in
return at some later time isn’t an option – the most common place
where this is the case is in components that need to interface with
actors, but are not actors themselves. Living outside of the actor
world, they cannot receive messages.
For situations such as these, there is Akka’s ask support, which
provides some sort of bridge between actor-based and future-based
concurrency. "
When does this situation apply, ie when to use Akka ask support ?
I'm using akka to create Actor requests that in turn create web service requests so I think this is a use case as I may not get a valid web service response in appropriate time frame. Also web service requests do not live in the Akka world. Am I correct in my reasoning ? What are the real world example where I should ask instead of tell ?

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.

Azure Service Fabric reliable actors vs reliable services

I am new to Azure Service Fabric and the biggest questions I have are
When should I use reliable actors? Give me practical examples please.
When should I use reliable services? Give me practical examples please.
Taken a look at the differences:
State analogy : Actors work on a single instance of an object graph.
Services usually have state for multiple callers.
Scope : Actors can’t work alone, because of their size (more like objects).
Life-cycle : Actors are only active when used, so
more will fit on your available server resources
Concurrency : Actors
enforce single threaded access
State : Actors just modify the
aggregate, services work on sets so often use transactions on sets
for ACID behavior.
Communication : Actors communicate through
channels provided by the platform. Services may choose otherwise.
Access : Actors in the cluster can’t be reached from the outside by
default. You’ll probably need a Service that provides access.
Samples when to use an actor:
For every user of your mobile app you could have one actor.
For every thermostat that sends information to your application you could have one actor.
For every customer of your e-commerce site, you could have one shopping-basket actor.
Create a service in the cases that you are probably used to. Create a reliable service that provides a service for multiple users at once. For example a weather service.
I don't mean to use a word to define itself, but use Reliable Actors only if you've determined your problem fits the actor design pattern. Actors are a design pattern much like many of the Gang of Four design patterns. If your problem fits one of the patterns, use it. If it doesn't, it's best not to try to shoehorn your problem into the wrong pattern.
In Service Fabric, Reliable Actors are an implementation of the Virtual Actor pattern. It has certain rules of operation and caveats that go with them. This is a good doc to read to get an idea of how the Reliable Actor framework works and whether or not it meets your requirements: https://azure.microsoft.com/en-us/documentation/articles/service-fabric-reliable-actors-platform/
Reliable Actors are in fact just a framework built on top of Reliable Services, so all the same scaling, partitioning, and distribution rule apply.

Akka, advices on implementation

I would like to create an app who integrate our (enterprise) specific tools with Slack. For that I can foreseen some bots who send events to Slack and a few commands who trigger actions.
I would like to use Akka because it is a buzzword and seems nice but don't have any arguments in favor of it. (It is not a problem since I will develop this app alone on my freetime).
But I don't have any experience on how to create an "Actor based application". I already have 3 actors, two to collect Events and one to publish those Events to Slack. Each collector are triggered by a timer, they hold a reference to the publisher and send message to him... that works..
For the commands part I din't have anything but can imagine a listener (Play http controller) who convert Slack requests to message and send them to one Actor. Ideally, I would like to decouple this listener from the Actor who will handle the command.
I would like to have some advices on how to develop this kind of applications where I have actors to collect information on a time basis and other to react to messages.
Thanks.
For time based activity, i.e. "ticks" or "heartbeats", the documentation demonstrates a very good pattern for sending messages to Actors periodically.
For your other need, Actors responding to messages as they come in, this is exactly the purpose of the Actor's receive method. From the documentation:
Actors are objects which encapsulate state and behavior, they
communicate exclusively by exchanging messages which are placed into
the recipient’s mailbox. In a sense, actors are the most stringent
form of object-oriented programming, but it serves better to view them
as persons: while modeling a solution with actors, envision a group of
people and assign sub-tasks to them, arrange their functions into an
organizational structure and think about how to escalate failure (all
with the benefit of not actually dealing with people, which means that
we need not concern ourselves with their emotional state or moral
issues). The result can then serve as a mental scaffolding for
building the software implementation.

Importance of Akka Routers

I have this lingering doubt in my mind about the importance of Akka Routers. I have used Akka Routers in the current project I am working on. However, I am a little confused about the importance of it. Out of the two below methods, which is more beneficial.
having routers and routees.
Creating as many actors as needed.
I understood that router will assign the incoming messages among its routees based on the strategy. Also, we can have supervisor strategy based on the router.
I have also understood that actors are also lightweight and it is not an overhead to create as many actors as possible. So, we can create actors for each of the incoming messages and kill it if necessary after the processing si completed.
So I want to understand which one of the above design is better? Or in other words, in which case (1) has advantage over (2) OR vice versa.
Good question. I had similar doubts before I read Akka documentation. Here are the reasons:
Efficiency. From docs:
On the surface routers look like normal actors, but they are actually
implemented differently. Routers are designed to be extremely
efficient at receiving messages and passing them quickly on to
routees.
A normal actor can be used for routing messages, but an actor's
single-threaded processing can become a bottleneck. Routers can
achieve much higher throughput with an optimization to the usual
message-processing pipeline that allows concurrent routing. This is
achieved by embedding routers' routing logic directly in their
ActorRef rather than in the router actor. Messages sent to a router's
ActorRef can be immediately routed to the routee, bypassing the
single-threaded router actor entirely.
The cost to this is, of course, that the internals of routing code are
more complicated than if routers were implemented with normal actors.
Fortunately all of this complexity is invisible to consumers of the
routing API. However, it is something to be aware of when implementing
your own routers.
Default implementation of multiple routing strategies. You can always write your own, but it might get tricky. You have to take into account supervision, recovery, load balancing, remote deployment, etc.
Akka Router patterns will be familiar to Akka users. If you roll-out your custom routing then everyone will have to spend time understanding all corner cases and implications (+ testing? :)).
TL;DR If you don't care about efficiency too much and if it's easier for you to spawn new actors then go for it. Otherwise use Routers.

What are the pros and cons of HTTP callbacks vs. message passing?

We are looking to develop a number of services, but are not sure which "response" mechanism is the best route to go. The two contenders are:
HTTP callbacks, where the service would update the client application via "pinging" it with update messages sent via HTTP requests
Message Passing, where the service would update the client via publishing messages into a pub-sub queue on a message server
In both cases, both the caller and the services are within our network, we have full control over them, and things we develop are the only users of the services.
What are the pros / cons of each way of providing status updates to the calling application, and what, if any, pros / cons would there be for making the initial request via one method or the other?
Note: The first service we have in mind for this is an email service similar to SendGrid, which we can't use for various reasons, but still need the same functionality.
The main difference would be the quality of service that you get "out of the box" with a messaging server.
If you go with HTTP then your application has to take care of what happens when a message doesn't arrive as expected. To get an idea of the issues you need to consider and the complexities involved in solving them, take a look at WS-ReliableMessaging or HTTPLR.
With messaging, you get a configurable level of reliability out of the box. And there's a lot of good choice these days such as ActiveMQ, RabbitMQ, 0MQ.
My personal preference is for reliability to be handled at the transport layer (by messaging), but then for a good discussion and dissenting view, check out "Nobody Needs Reliable Messaging."