AKKA: Communicating via Messaging Queue - scala

We have a component written in Groovy ( let's call it a "G-Component" ) that needs to communicate with a component written in Scala / AKKA ( let's call it an "A-Component" ).
What fits our needs best is a messaging queue:
"G-COMPONENT" <==> in memory messaging queue <==> "A-COMPONENT"
For the "G-COMPONENT" life is simple:
queue.send( message )
message = queue.receive()
For the AKKA component it seems a bit more involved, since there is an Actor that needs to "handle"/"receive" messages, and be able to "send" messages back.
The problem is the "receive" part, as it now needs to go into a loop of its own to listen for messages from the queue. Which.. disables it as an AKKA Actor, since once it is in that loop, it can't receive any AKKA messages.
Would appreciate any help on the clean solution for this, without implementing an AKKA plugin of "that particular queue implementation" Actor mailbox.

converting a "question edit" to an answer
Found an interesting development going of not yet officially released AKKA API:
"Akka provides a ZeroMQ module which abstracts a ZeroMQ connection and therefore allows interaction between Akka actors to take place over ZeroMQ connections."
Seems that I can have an AKKA way to spawn a ZeroMQ listener:
val listener = actorOf(new Actor {
def receive: Receive = {
case message: ZMQMessage => ...
case _ => ...
}
}).start
val socket = ZMQ.newSocket(SocketParameters(context, SocketType.Sub, Some(listener)))
socket ! Connect("tcp://127.0.0.1:1234")
socket ! Subscribe(Seq())
confirmed by Viktor Klang (question comments) this is the way to go

This may be obvious but Akka has excellent camel and amqp integration.
http://akka.io/docs/akka-modules/1.2/modules/camel.html
http://akka.io/docs/akka-modules/1.2/modules/amqp.html
I am not sure what you mean by 'without implementing an AKKA plugin of "that particular queue implementation" Actor mailbox'. Does that mean you don't want to use these components?

AKKA is a library not a programming language.
Just write the zeromq message listener outside of an actor, and have it send incoming zeromq messages to AKKA actors. I've done this with AMQP using the Java AMQP client library and it works just fine.
If you want the ZeroMQ listener to be running in an event loop, then it is easy enough to write your own using the select poller http://api.zeromq.org/2-1:zmq-poll Have a look at the ConcurrentSocketActor source code in the AKKA zeromq module because that's what it uses. This would be a good model if you ever need to roll your own concurrent actor for some other type of network communication.
And this is the same problem that people have when they want to add a network accessible management interface to a non-network application in any language.

Related

How to test an actor?

How can I test an actor? Since the calls are not synchronous, and one messages can cause multiple messages to be sent, what are the ways of testing it?
E.g. How can I test that my actor sent 3 messages in response to another message?
In general you cannot test what an actor has done unless it interacts with a trait or interface you provide in the construction or in an input message. So if you have an actor like the following.
actor MyActor
be do_stuff(receiver: MyReceiver)
You use a pattern where you combine a timer, for a timeout, and a wrapper actor that provides MyReceiver to test if the actor actually did send the message or sequence of messages that where expected.
Pony already includes the ponytest package with some support for this kind of tests. You can check the PonyTest actor at GitHub. Basically you have to specify a timeout and ensure one of your actors calls complete in the test helper for success. Note that the API has changed since the last stable version.

Does the ask pattern work with Akka IO actors?

Say I have an IO Actor connection capable of sending and receiving messages over TCP. In my actor, I ask the other side of the connection for a response:
connection.ask(ByteString("stuff")).collect {
case Received(response) => log.debug(response.utf8String)
}
It appears that with this code the ask future times out, and instead the containing actor receives the raw message outside of the ask pattern.
Can you use the ask pattern with Akka IO actors? If not, why not?
I don't know the architecture in detail, but here's how I would explain it to myself:
The problem with Akka IO connector actors here is that they don't work in a request-response manner. And if you think about it - that makes sense, because TCP is not a request-response protocol. TCP doesn't even have a notion of message. From programmer's perspective TCP connection is just a pair of continuous byte streams - one in each direction. That's it.
Akka IO is a minimal actor layer on top of network protocols, so it's not surprising that it mimics this behaviour. When TCP actor receives some data from the network, it only knows one thing - that it should send a Received message to the actor that originally sent the Connect message. That's all. It has no idea that the data it received from the network is somehow related to the data that you sent earlier.
Adding to all of that, ask pattern works only under assumption that when you send message A to some actor, it will respond with the message B by sending it exactly to the sender of message A. As we already know, TCP actor doesn't do that - it simply sends everything to the sender of original Connect message.
The reason why this assumption is required is that ask pattern actually creates some sort of a "phantom" actor that is set as the sender of the message sent using ask. This "phantom" actor will then receive the response and invoke all the callbacks registered on the Future. As a side note - be aware that those callbacks are invoked completely independently of the sending actor, i.e. they may run concurrently to it!
So, I would finally conclude that the ask pattern used like this will not work with Akka IO, because it's simply too low level for such an abstraction. If you still want it, you need to create you own layer of abstraction on top of Akka IO, e.g. some simple intermediate actor that covers TCP connector actor and implements the request-response behaviour.
As an additional reference to #ghik's answer, here's roughly how I created an intermediate actor to enable the ask pattern for IO on the rest of my actors.
class IOAskHandlerActor(address: InetSocketAddress) extends Actor {
override def receive = {
// Connection setup code omitted
case Connected(remote, local) =>
// other code omitted
context become latch(sender())
}
def latch(connection: ActorRef): Receive = {
case outgoing =>
context become receiving(connection, sender())
connection ! MySerializer.write(outgoing)
}
def receiving(connection: ActorRef, asker: ActorRef): Receive = {
case Received(incoming) =>
context become latch(connection)
asker ! MySerializer.read(incoming)
}
}
Instances of this class can be asked for responses. Note that I have only tested this with one simultaneous asker (which is my use case) and this probably doesn't work for multiple askers.

Scala and akka lifecycle.. again

So this question is related to an old one of mine: Do I need to re-use the same Akka ActorSystem or can I just create one every time I need one?
I asked a question about the lifecycle of actors, and I knew something was wrong in my mind, but couldn't phrase it correctly. Hopefully I can now :-).
Here's the situation. I want to test actors that have dependencies to other components and actors, so I went about composing my actors in bootstrap time (I'm using scalatra but however you bootstrap your app). I therefore have something like this:
trait DependencyComponent
{
val dependency : Dependency
}
trait ActorComponentA extends Actor with DependencyComponent {
val actorB : ActorRef
}
trait ActorComponentB extends Actor with DependencyComponent
Ok, so now I can test my actors by extending the traits and providing mock dependencies, all good. And I can bootstrap my app like so:
Bootstrap
val system = ActorSystem()
val actorA = system.actorOf(Props[DefaultActorA])
class DefaultActorB extends ActorComponentB {
val dependency = new RealDependency()
}
class DefaultActorA extends ActorComponentA {
val dependency = new RealDependency()
val actorB = context.actorOf(Props[DefaultActorB]).withRouter(RoundRobinRouter(nrOfInstances = 100)))
}
Cool, Im happy :-), now I can use the actorSystem and actorA within my app, and it has a 100 actorB routed to pass work to. So when actorA decideds that the work is done, it's my understanding that it should broadcast to the routed actors to shutdown. At this point when another request comes in actorA can no longer send messages to the router because all its actors are dead.
If I wasn't setting this up at boot time then actorA and its dependencies could be created when needed in my app. But that is very much like "newing up on object" in DI world. In order to test I would end up overriding the places where the actors were created.
Scalatra docs are suggesting creating my actors at boot time, so I feel that I am missing somehting here. Any help appreciated.
Cheers, Chris.
EDIT
I've +1 both #futurechimp and #cmbaxter as these both seem valid but slightly conflicting. So this is an open comment to both of you.
So #cmbaxter am I right in thinking that your suggesting never calling 'stop' on the routed actors and just maintaining a pool of them for use by ALL requests. And #futurechimp, your suggesting having the servlet instantiate the actors per request and killing them at the end of there lifecycle. Right?
It seems like per-request will spawn more actors (but dispose of them). Where the poll will have only a limited set for all requests in which case is there a potential bottle neck to this approach?
I guess basically, I'm asking if my assumptions are correct and if so what are the advantage and disadvantages to both approaches?
Instantiating an ActorSystem is expensive - however instantiating an Actor isn't. If you only want to instantiate your ActorSystem in ScalatraBootstrap, and your Actors elsewhere, that should work fine if that's what you need to do. I'll talk to some other people to confirm this, and then change the docs in Scalatra's Akka Guide to avoid confusion in future.
One of the questions you have to ask yourself here is: Are my actors going to be stateful or stateless. If stateless (and I would prefer this approach personally when possible), then they can be "long-lived" and you can start them when the server boots up and leave them running for the duration of the server's life. When you need to talk to them from elsewhere in the code, use system.actorFor(String) or system.actorSelection(String) (depending on what version of akka you are using) to look up the actor and send it a message. If the actors are going to be stateful, then they probably should be "short-lived" and started up in response to an individual request. In this case, you will not start them up when the server boots up; you will only start up the ActorSystem itself. Then, when the request comes in, you will instantiate via system.actorOf instead and make sure that when the work is done that you stop ActorA as it's the supervisor of all the ActorBs and stopping A will stop all of the Bs started by A.

How to "ask" an ActorSelection

How do I "ask" an actor that should be provided by its path?
ask(context.actorSelection("../foo"), GetInfoMessage)
…results in an ActorSelection but only ActorRefs can be "asked".
Alternatively, context.actorFor returns an ActorRef, but this function is deprecated according to the documentation.
Since Akka 2.2.1 you can use ActorSelection.resolveOne to get an ActorRef from a selection:
http://doc.akka.io/api/akka/2.2.1/index.html#akka.actor.ActorSelection
Then you can ask the ActorRef as you normally do
Later on that page you will see
To acquire an ActorRef that is bound to the life-cycle of a specific actor you need to send a message, such as the built-in Identify message, to the actor and use the sender reference of a reply from the actor.
So it's a three step process. Use actorSelection, then send Identify, then ask.
This is only for Akka 2.2 though, so in Akka 2.1 or prior you still need to use actorFor.
The rationale is explained in the 2.2 Migration Guide.

What is the best way to implement a request/response protocol using akka and scala?

I've been studying about how I could develop a distributed architecture that implements the protocol request/response using the concept of concurrency through actors.
I concluded that the best way to do this is by creating a response system with synchronous handling of Futures/Promises, and soon after the response, leaving an open channel to receive notifications.
Thus an architecture that would work exactly like a inbox message.
It has some problems.
Thus I would have to maintain two endpoints (actors in the two layers)?
The Problem:
The view module requests that a particular element is processed. She sends this command to be processed via RemoteActor on the application server. This server should immediately return the promise that it will notify you when the element is processed. After this, the view module will be waiting the notification of completion of processing.
How do you see this problem?
I am using Scala, Akka and Google Guice.
I believe it is a generic problem that everyone can make use of their solutions. Excuse me if I'm hurting the terms of stackoverflow site.
Thanks in advance
I don't want to distract from any good answers you may get on Akka, because I unfortunately don't know much about Akka and it's distributed actors features, but I'd like to ask if you've considered any alternatives.
It seems that you basically need an asynchronous RPC library. There are two powerful libraries written in Scala that I know of that may satisfy your requirements - http://sna-projects.com/norbert/ and http://twitter.github.com/finagle/. Finagle gives some really powerful combinators for expressing asynchronous computation dependencies and registering listeners on futures. I'm currently maintaining Norbert, which we use at LinkedIn for some of our distributed systems, such as search.
//On "server" node
class SomeActor extends Actor {
def receive = {
case messageToRemoteActor => self reply_? TypeOfResponseMessage()
}
}
Actor.remote.register("myRemoteActor", actorOf[SomeActor])
//On "client" node
val remoteActor = Actor.remote.actorFor("myRemoteActor", "hostnameOrIpOfNodeContainingTheActorAbove", port)
val f: Future[TypeOfResponseMessage] = remoteActor !!! messageToRemoteActor
f.onComplete( _.value.get match {
case Left(exception) => handle(exception)
case Right(result) => handle(result)
})
Why not just use one of 0MQ's REQ-REP sockets?
https://github.com/zcox/akka-zeromq-java
That way you solve your immediate problem and at the same time, begin learn an architecture that will take you a long way and supports communications with clients written in many languages.
For an example of where this might lead look at http://blog.getintheloop.eu/2009/05/22/lift-amqp-with-rabbitmq-and-scala-tutorial-and-screencast/
Note that I am NOT suggesting that you use AMQP today since a RabbitMQ broker would be overkill for your immediate problem. Rather, I am suggesting that you invest your time in using an architecture (message queueing) that will pay you dividends in the long run.