A sample application showcasing play-mini and Akka
In Akka 2.0 we have decided to replace the Mist based HTTP module with a module called play-mini. With play-mini it’s possible not only to create REST based API in an easy fashion but also to use the power of the Play framework.
In this post we will describe the steps needed to build a simple REST service and have it interact with actors in an ActorSystem. It will also show the power of Akka’s futures and how to apply them in a real world example.
If you are not familiar with the infinite monkey theorem you can study the background of the application here: http://en.wikipedia.org/wiki/Infinite_monkey_theorem
(Disclaimer: the sample application used is not a complete implementation, or a proof, of the theorem in any way.)
Prerequisites
- SBT 0.11.2 installed
- IDE of your choice (we recommend Eclipse, IntelliJ, <insert your favorite IDE here>)
- Git (not mandatory but simplifies things [which is something that can be said about Git in general])
Download the Application Code
Start by downloading the code to your local machine. Open a terminal and type the following:
> git clone git@github.com:henrikengstrom/PlayMiniSample.git
> cd PlayMiniSample
> sbt
sbt> compile
That last command will print a lot of traces but it should end with something similar to:
[info] Compiling 2 Scala sources to /<your_structure>/PlayMiniSample/target/scala-2.9.1/classes…
[success] Total time: 5 s, completed Feb 19, 2012 10:31:41 AM
Okay, that’s it. Now you have the code downloaded and compiled.
Before giving the application a spin it’s a good idea to go through the different parts so you get a better understanding of it all.
Application Dissection
Play-mini gives you the tools to create a REST API and also easily have it integrate with your ActorSystem. You need to do 2 things in order to create a play-mini application:
- Create a Global class to indicate to play-mini what class to run
- Have your play-mini class extend com.typesafe.play.mini.Application:
Routing
When extending com.typesafe.play.mini.Application you have to provide a route implementaion. This is where the routing logic should go, i.e. where you add all URL paths the application should handle.
The sample application handles two paths:
- HTTP GET /ping
- HTTP POST /write
The anatomy of the route method is to first state the HTTP method and thereafter what path the method should be applied to, e.g.:
GET(Path(“/ping”)) or
POST(Path(“/write”))
The result returned is a “Action”. For more information about this see:
https://github.com/playframework/Play20/wiki/ScalaActions
Let’s dissect the HTTP POST in the sample.
Interesting lines are:
Line 1: Declares HTTP method and path. Also adds an “implicit request”. The latter part is required by line 3, i.e. the form handling.
Line 3: Extracts parameters posted in the request with help of the Form extractor (line 17).
Line 4: AsyncResult instructs the code to park the HTTP request and release the thread.
Line 5: This is where the call to Akka is done with “shakespeare ? numberMonkeys”. This returns an Akka Future instance and that Future is then mapped to the case class “Result”. (The rest of the code, i.e. “.asPromise.map” is merely a way of converting from an Akka Future into Play’s own Future implementation.)
Line 7-11: Builds the reply, in this case a simple string.
Line 12: Returns the result. There are a a set of predefined replies pre-defined in Play (for more info see: https://github.com/playframework/Play20/wiki/ScalaActions)
The ActorSystem
Our infinite monkey theorem implementation is quite simple. It consists of two actor types; Shakespeare and MonkeyWorker.
The former receives information about how many monkey workers to use, creates the actors and sends a generated random number which instructs the monkey worker how many words to type.
A nice feature that should be described in a little more detail is the use of Akka’s Future implementation. Shakespeare seems to have been quite an astute chap and the same can be said about the Futures implementation in Akka!
Line 3-5: This is the part where we create the actors and sends them information about how many words to type. Since we use the ask notation (“?”) this means that we get a Future back, or as in this case a list of Future. Noteworthy is also that the result of each Future will contain a set of strings and this is interestingly enough also what the money workers send back to the “sender” as a message.
Line 7: Extracts each result from the list of futures
Line 8: Merges all results into one result (Set[String])
Line 9: Divides the result into two subsets; Shakespearian and non-Shakespearian words
Line 10: Creates an instance of the case class Result
Line 11: Pipes the result back to the “sender” which in this case is the HTTP POST part in the route method.
Fore more information about the Akka Future implementation see: http://akka.io/docs/akka/2.0-RC1/scala/futures.html
We leave it to the reader to investigate how the MonkeyWorker has been implemented.
Running the Application
Want to give the application a test ride?
Just type the following in the terminal window:
>sbt
sbt> run
You should now see something like:
[info] Running play.core.server.NettyServer
Play server process ID is 30095
[info] play - Application started (Prod)
[info] play - Listening for HTTP on port 9000…
Fire up another terminal window and try it out:
> curl http://localhost:9000/ping
Pong @ 1329654200089
That went fine so the application seems to be alive and kicking. Now let’s get them monkeys busy:
> curl -d “number=1” http://localhost:9000/write
SHAKESPEARE WORDS:
UNWORTHY WORDS CREATED: 56
In 40376us
Okay, so using one monkey is probably not enough to create Shakespearian words. Let’s try with 100 monkeys:
> curl -d “number=100” http://localhost:9000/write
SHAKESPEARE WORDS:
or
UNWORTHY WORDS CREATED: 4691
In 133460us
Yeah, they typed an “or”. Let’s use one thousand monkey and see what words they can come up with:
> curl -d “number=1000” http://localhost:9000/write
SHAKESPEARE WORDS:
or
to
not
be
UNWORTHY WORDS CREATED: 45773
In 219808us
Who said that writing Shakespeare couldn’t be done by monkeys? :-)
Further reading
- Play-mini: https://github.com/typesafehub/play2-mini
- Akka: http://akka.io
- Play: http://www.playframework.org/2.0
Happy hAKKing
@h3nk3
Akka 2.0 Remoting with Java
There have been a lot of requests for a Java example of how to use the remoting capabilities in Akka 2.0 and now there is one. It can be found here:
https://github.com/jboner/akka/tree/master/akka-samples/akka-sample-remote
Some interesting highlights are:
Looking up a remote actor on a remote node:
Creating an actor on a remote node:
As you can see there isn’t much to the code itself and this is because everything is configuration driven.
Here is what the configration files look like:
and
That’s it! Pretty slick right.
Happy hAKKing
//h3nk3
Location Transparency: Remoting in Akka 2.0
The remoting capabilities of Akka 2.0 are really powerful. Something that not has been as powerful is the documentation of the Akka remoting. We are constantly striving on improving it and this blog post will, hopefully, shed some light on the topic.
The remoting contains functionality not only to lookup a remote actor and send messages to it but also to deploy actors on remote nodes. These two types of interaction are referred to as:
- Lookup
- Creation
In the section below the two different approaches will be explained.
(It may be worth pointing out that a combination of the two ways is, of course, also feasible)
The Setup
In order to run the example code below the following jars must be available on your classpath:
- akka-actor.jar
- akka-remote.jar
The Configuration File
Firstly we’ll start off by examining the configuration file as it plays a pivotal part in the remoting. The remote section holds a lot of configuration possibilities but the bare minimum to get started is described in this section:
If you want to run multiple actor systems on the same machine you can group your settings like this:
Okay, so basically what you need to do to get started are four things:
- Make sure that the
akka.remote.RemoteActorRefProvideris used as provider - Add host name - the machine you want to run the actor system on
- Add port number - the port the actor system should listen on
- Add cluster node name - must be a unique name in the cluster
The above settings are enough for the lookup approach. In that case we only need to make sure the involved actor system run on a unique combination of host name and port.
Let’s say we are interested in testing the other approach, i.e. the creation functionality of remoting. This means that we have to add some information to the configuration file:
The configuration above instructs Akka to react specially once when an actor at path /actorName is created, i.e. using system.actorOf(Props(...), "actorName"). This specific actor will not only be instantiated, but instead the remote daemon of the remote system will be asked to create the actor instead,which is at actorSystem@127.0.0.1:2553 in this sample.
Lookup Approach in code
Let’s say you want to look up an actor on a remote node and use it. It’s really simple! Just do the following:context.actorFor("akka://ACTOR_SYSTEM@HOST:PORT/user/ACTOR_NAME")
where:
ACTOR_SYSTEMis the name of the actor system the actor exists inHOSTis the machine address, e.g.127.0.0.1PORTis the port number the actor system is configured to listen to, e.g. 2552ACTOR_NAMEis the name of the actor you want to use
The actor you want to use has to exist in the actor system and have the name associated with it. Here’s some example code how to set it up and try it out:
Creation Approach in code
In this section we will see how to create and use and actor on a remote node:
A fully fledged example of the two approaches can also be found here:
https://github.com/jboner/akka/tree/master/akka-samples/akka-sample-remote
Happy hAKKing
@h3nk3