Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Akka in Practice

Akka in Practice

Real World Application Design Patterns for the Intermediate Akka Developer, Scala Exchange 2013

Raymond Roestenburg

December 02, 2013
Tweet

More Decks by Raymond Roestenburg

Other Decks in Programming

Transcript

  1. PRACTICE AKKA Real World Application Design Patterns for the Intermediate

    Akka Developer @agemooij !@rayroestenburg ! [email protected][email protected] ✉ in Scala Exchange December 2nd 2013
  2. Introduction ➡ BUILD A REST API WITH AKKA ➡ HANDLE

    REQUESTS ➡ EXECUTE EVENT-DRIVEN (BACKGROUND) TASKS The context for this talk..
  3. Introduction Solutions for typical scenarios ➡ STRUCTURE THE ACTOR HIERARCHY?

    ➡ CONFIGURE ACTORS? ➡ KEEP TESTING SIMPLE? ➡ HANDLE REQUESTS? ➡ BUILD BACKGROUND SERVICES? ➡ DECOUPLE REQUESTS FROM BACKGROUND SERVICES? ➡ AND SOME MORE… How do I:
  4. Agenda ➡ BOOTING UP ➡ THE RECEPTIONIST ➡ CREATING CHILDREN

    ➡ BECOME ➡ CONFIGURATION BY EXTENSION ➡ STREAMING EVENTS ➡ EVENT-DRIVEN SERVICES ➡ REQUEST/RESPONSE
  5. The Receptionist: ➡ How do we get Akka to actually

    do some work? ➡ We need to talk to the actor system from the “outside” ➡ We need a “receptionist” to take our calls “Just use a socket!” Akka IO supports TCP, UDP, and HTTP We will use Spray, a.k.a. akka-http
  6. The Receptionist: Your entry-point actor can use Spray’s routing DSL

    to handle requests “But who is going to do the work?”
  7. Creating Children: ➡ Every actor should do one thing and

    one thing only! ➡ When it all gets too much, use child labor! ➡ Children help with separation of concerns ➡ Use supervision to deal with failure
  8. Creating Children: ➡ Create a child to do the hard

    work ➡ Here we use the “ask” pattern and futures in order to produce an HTTP response ➡ There are other ways! “But how do you MOCK this?”
  9. Creating Children: ➡ Direct use of context.actorOf is hard to

    stub/mock ➡ This is OK for simple children because Akka TestKit is awesome ➡ But for more complex child hierarchies, it would be nice if we could stub/mock child actors
  10. Creating Children: ➡ Layer traits based on least required dependency

    ➡ ActorCreationSupport can be mixed with anything ➡ ActorContextCreationSupport requires context
  11. Creating Children: ➡ Mix in a trait for creating children

    ➡ Override during testing “How to test the http ROUTES?”
  12. Creating Children: ➡ Put the routes in a separate Routes

    trait! ➡ Routes says: “I need ExecutionContext & CreationSupport!”
  13. Creating Children: ➡ Layer traits based on least required dependency

    ➡ ActorCreationSupport can be mixed with anything ➡ ActorContextCreationSupport requires context TestCreationSupport creates a FakeProcessJobActor
  14. Initializing Actor State: ➡ Say an Actor uses a “Stuff”

    library ➡ Stuff needs some time to start… (returns Future) “VARS? Concurrent Access?”
  15. ➡ Initialize the actor using messages ➡ Only process messages

    once initialized ➡ Possibly stash messages away until ready ➡ Crash when initialization fails (parent handles failure) Initializing Actor State:
  16. Initialization using become: ➡ Allows you to build simple state

    machines ➡ Use multiple receive functions and switch behavior ➡ No need for vars!
  17. Become is powerful sh*t: ➡ Allows you to build simple

    state machines ➡ Switch behaviour at runtime based on internal state ➡ Makes it possible to model processes and flows
  18. Configuring Akka Apps: ➡ We all know hardcoding configuration is

    evil ➡ We don’t want to use a heavyweight DI library for some simple settings ➡ How can we configure our Akka apps?
  19. Using Settings: ➡ Access your Settings wherever you have a

    reference to an ActorSystem or an ActorContext
  20. Settings extension: ➡ A simple example of an Akka extension

    ➡ Simple to use ➡ Configure for test, dev or production
  21. Using Akka’s EventStream: ➡ How to communicate between disconnected actors?

    ➡ You don’t always have (or need) a reference to all actors in the system who might care about your messages
  22. Using Akka’s EventStream: ➡ Messages that you have subscribed to

    are routed to your receive method like any other actor messages
  23. A background service: ➡ Is started by the Receptionist ➡

    Is supervised by the Receptionist ➡ Subscribes to events / commands on startup ➡ Unsubscribe can be put in a trait, mix in with background service
  24. An activation email background service : ➡ Sending scheduled activation

    and reminder emails ➡ Coordinator subscribes to Registration Events ➡ ActivationEmailSender schedules mails ➡ Emailer sends mail using SMTP “How do I test this stuff?”
  25. Expect events! ➡ Don’t try to assert intermediate messages ➡

    Events should occur as the result of the process ➡ Subscribe the testActor to specific Events ➡ Expect the events with the TestKit
  26. Using Akka’s EventStream: ➡ The EventStream is great for monitoring

    what happens in your system ➡ Actors can easily subscribe to events ➡ It is also great for making your application easier to test
  27. Complex request/response ➡ So far we have used the “ask”

    pattern and futures to do request/response with actors ➡ But what happens when the request handling flow gets a bit more complex?
  28. Complex request/response ➡ Define traits that return Futures ➡ combine

    the futures with map, flatMap & friends ➡ Implementation asks Actors (or uses Futures directly)
  29. Complex request/response ➡ This might or might not be your

    cup of tea… ➡ There are other ways to model a sequential flow of information…
  30. Complex request/response ➡ We can use our old friend Become

    in a single-use actor ➡ We do need to make sure it gets killed after it is done ➡ We also need to take care of timeouts ourselves “Worth the complexity?”
  31. Request / Response: ➡ ‘Future Traits’ ➡ Use Actors or

    Future supporting API directly ➡ Mixin into Routes ➡ Single Purpose Actors also possible ➡ setReceiveTimeout ➡ Kill afterwards
  32. HTTP and domain ➡ Separate HTTP logic and domain logic

    ➡ Spray JSON ➡ Routes trait handles HTTP ➡ Deserialization (parameter values) ➡ Unmarshalling (entity body) ➡ Complete the response (StatusCodes, JSON)