Integrating Grails and Akka

Grakka is a simple demonstration application showing how to integrate Grails 3.x and Akka 2.4.

Grakka integrates Grails and Akka following the same Spring context integration approach demonstrated in Typesafe’s activator-akka-java-spring demo.

The key of the design is to make the Spring context responsible for creating both Grails objects and Akka actors. Since Spring is responsible for object creation, a number of nice features are available automatically:

  • Grails objects may be injected with Akka objects, e.g. NumberController is injected with the ActorSystem
  • Akka actors may be injected with Grails objects, e.g. NumberActor is injected with a Grails Service

The availability of bi-directional injection of resources enables the application designer to decide which way(s) dependencies should flow through the application.  Grails and Akka are both powerful platforms and careful consideration should be given to how the two should be blended, particularly whether features like GORM should be used within an Actor since that Actor might exist in a remote JVM (someday).

Implementation of the Integration

There are a few classes that collaborate to implement the integration, all in grails-app/utils/conf:

  • AkkaSpringConfiguration – a Spring context definition that defines the Akka actor system as a Spring bean, supplementing the standard Spring context defined by Grails by importing the context in resources.groovy
  • SpringExtension – an extension to the Akka actor system that enables actor creation to be performed by the SpringActorProducer
  • SpringActorProducer – an implementation of Akka’s IndirectActorProducer that delegates actor creation to Spring, enabling injection of Grails objects

The AkkaSpringConfiguration uses Spring’s Configuration annotation to identify itself as a provider of Spring beans and is found automatically on Spring’s scan of the classpath on startup.  AkkaSpringConfiguration provides the actorSystem bean, an instance of ActorSystem.  When creating the ActorSystem, a SpringExtension is registered with the ActorSystem that enables actors to be produced via the Spring applicationContext.

Akka relies on Props objects to describe the type and configuration of Actors to create. The SpringExtension provides a ‘props’ factory method that creates Props instances which delegate actor creation to the SpringActorProducer so that actors can be created by name:

The SpringActorProducer‘s produces actor instances by getting a bean of the desired type from the Spring applicationContext:

The produce method must produce a fresh actor instance upon each invocation, so a Spring prototype bean configuration implements it nicely.

Integration in Action

The integration of the Spring and Akka object creation processes enable Grails to use Akka and Akka to use Grails.

For example, the Grails NumberController is injected with the ActorSystem via Grails’ standard process of injecting Grails object instances with beans from the application context.  NumberController’s actorSystem can then be used to create and use NumberActor instances:

The NumberActor created by the Spring-integrated ActorSystem has been injected with the NumberService, which provides a ‘nextInt’ method to generate random integers:

The grakka application can be run via the standard ‘grails run-app’ command.  Once running, grakka’s random integer generator can be accessed with a GET to the /number/random endpoint:

$ curl -v http://localhost:8080/number/random
*   Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
> GET /number/random HTTP/1.1
> User-Agent: curl/7.40.0
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< X-Application-Context: application:development
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Wed, 20 Jan 2016 04:50:46 GMT
<
* Connection #0 to host localhost left intact
{"id":"192d7089-aba6-40d1-9c02-a8664ee6ed52","randomInteger":465221946}

Conclusion

The Grakka example app introduces some of the possibilities for integrating Grails and Akka.  With both integrations of Grails→Akka and Akka→Grails demonstrated, the application designer can decide if they need one or both directions and modify the integration accordingly.

Thanks

Thank you very much to the folks who built the platforms that made grakka possible: