What is the best way to implement a request/response protocol using akka and scala? - 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.

Related

How to dynamically check type of an actor

It is a general question about developing with akka actor system.
I know, it sacrifices static type checking for greater flexibility, that is not the problem. Java does the same thing all the way.
But I'd like at least to check compatibility of ActorRefs dynamically. I searched for some method like actorRef.asInstanceOf[ActorType]. Such method should provide validation for an actorRef passed through messages. And it would allow safe application development. But I've found no method to do any kind of type check. Its even impossible to check if an actorRef correspond to given Props.
How this task typically solved in akka application? Are there any third-party tools for dynamic checks?
The purpose of ActorRef is to completely abstract the recipient. Sending a message to it provides absolutely no guarantees about a response or even suitability of the message being sent. The recipient could drop the message, route it, stash it or handle it. Any contract about handling and causing possible response messages to be emitted is entirely an informal agreement.
Now, that sounds like a lot to give up in a statically typed environment, but it provides a programming model that brings its own slew of advantages which by their design require that you are sending and receiving messages with the assumption that the messages will be handled but without any knowledge where or when they will be handled.
Regarding how this task is typically solved in akka applications is by configuration and/discovery. The contract of acceptable Messages is usually placed into a Protocol object, while the valid recipient for those Messages is either injected into the calling Actor at creation or queryable via some DiscoveryProtocol (itself hidden behind an ActorRef)
Let's say you have a UserRepository you want to query, you would create protocol like this:
case class User(id: Int, ... )
object UserRepositoryProtocol {
case class GetUser(userId: Int)
}
Further, let's assume that the ActorRef of UserRepository was not injected, but because it is just one of many services your actor might use has to be discovered via a general Discovery service:
object DiscoveryProtocol {
case class Discover(type: String)
case class Discovered(type: String, ref: ActorRef)
}
Now you can fetch a user like this:
(discoveryRef ? Discover("UserRepository")).flatMap {
case Discovered("UserRepository",repository) =>
(repository ? GetUser(id)).map {
case user:User => // do something with the user
}
}
The above condenses discovery and calls into a chain of ask operations. Chances are you would want to cache the discovered ref and or hand off the retrieved user to some other Actor that's doing the work, breaking each '?' into a ! and a matching receive in the same or different actor.
This last point illustrates the power of the actor model. In a traditional request => response model, the requestor and recipient of the response would have to be the same just by virtue of function signatures, but in the actor model, you can send from one actor, spawn a worker that will handle the response, etc.
Assume that an actor is not only encapsulated behind an actor ref, but that the physical location of an actor is also unknown. An actor can be running on another physical server or VM. You can't call instanceOf on an object in another VM - how can you expect to get the class of an actor then?
Now, when building, I would recommend you consider that all actors are remote via Akka's location transparency. (http://doc.akka.io/docs/akka/snapshot/general/remoting.html) If you assume all actors are remote, suddenly you'll think about your designs a little differently. Think of Akka as a Distribution Toolkit - that is its primary benefit!
If you're trying to reflect on actors during runtime, then there is probably something wrong with your design. Instead, you need to know what messages actors can accept and respond to.
If you really want to know what an actor can and can't do, then you could think of modelling some sort of "Accepts" method where an actor would reply with the current version of the described API that the actor implements for example - in this way your client and server can talk back and forth about what capabilities etc are supported dynamically during runtime.
I hope that contributes something to the discussion - just remember to always think of an actor as something that's running somewhere else and you'll design appropriately. The benefit of doing so is that you'll be able to scale out your applications with very minimal effort if your user base unexpectedly explodes!

Do Play WebSockets support back-pressure?

I need to add a WebSocket-to-TCP proxy to my Play 2.3 application, but while the outgoing TCP connection using Akka I/O supports back-pressure, I don't see anything for the WebSocket. There's clearly no support in the actor-based API, but James Roper says:
Iteratees handle this by design, you can't feed a new element into an
iteratee until last future it returns has been redeemed, because you
don't have a reference to it until then.
However, I don't see what he's referring to. Iteratee.foreach, as used in the examples, seems too simple. The only futures I see in the iteratee API are for completing the result of the computation. Should I be completing a Future[Unit] for each message or what?
Iteratee.foldM lets to pass a state along to each step, much like the regular fold operation, and return a future. If you do not have such a state you can just pass Unit and it will behave as a foreach that will not accept the next step until the future completes.
Here is an example of a utility function that does exactly that:
def foreachM[E](f: E => Future[Unit])(implicit ec: ExecutionContext): Iteratee[E, Unit] =
Iteratee.foldM[E, Unit](Unit)((_, e) => f(e))
Iteratee is not the same as Iterator. An Iteratee does indeed inherently support back-pressure (in fact you'll find yourself with the opposite problem - by default they don't do any buffering (at least within the pipeline - of course async sockets still have receive buffers), so you sometimes have to add an explicit buffering step to an enumerator/iteratee pipeline to get reasonable performance). The examples look simple but that just means the framework is doing what a framework does and making things easy. If you're doing a significant amount of work, or making async calls, in your handlers, then you shouldn't use the simple Iteratee.foreach, but instead use an API that accepts a Future-based handler; if you're blocking within an Iteratee then you block the whole thing, waste your threads, and defeat the point of using them at all.

How do you know what messages you can send to actor?

Is there any standard way of formalizing my scala/akka actor api? Imho, situation where I need to look into implementation to know what to send is not really a good option. Also, if implementation has changed and my message is no longer valid(not invoking action I think it invokes) I don't get any warning or error.
This is a question that is discussed very much in the community. I heard that maybe Akka 3 will have better support for typesafe actors, but that is some time down the road.
In the mean time you could use TypedActors, though the general suggestion is to use them at the boundaries of your application.
A nice approach that does not give you any typesafety, but makes the contract of an actor more visible, is to define the messages an actor can receive in their companion object. This way each time you want to send a message to an actor you choose from the message its companion object defines. This of course works best if you have specific messages for each actor. If you change the implementation you could remove the old message and add a new one, so that everyone who wanted to use the old implementation would get compiler errors.
Lastly there was a nice pattern last week on the mailing list. He creates traits to define the contracts for the actors and their consumers, but you still need to take care that the consumer mix in the correct trait.
In my experience, the best way to make sure everything works is an extensive test suite which will test each actor for itself, but also the communication between specific actors.
The approach generally taken in Erlang is to avoid sending messages to a process directly, and to provide additional API in the same module which defines the behavior of the process. In Akka it would look like
class Foo extends Actor {
// handles messages Bar(x: Int) and Baz
}
object Foo {
def bar(foo: ActorRef, x: Int) = foo ! Bar(x)
def baz(foo: ActorRef) = (foo ? Baz).mapTo[TypeOfResponseToBaz]
}
One problem is handling return messages, since Erlang generally promotes more synchronous style than Akka does. This may be handled by a naming convention (e.g. BarResponse or FooBarResponse if different actors handle the same message with different responses).

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.

AKKA: Communicating via Messaging Queue

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.