Are there patterns for writing a library that hides its actor system implementation?

99 views Asked by At

All of the actor system implementations I have seen (primarily using Akka) presume a web app, meaning an HTTP interface that can quite naturally be served by an asynchronous actor system.

But what if I'm writing a desktop app, or a library to be used as a component of a platform-independent app?

I want client subroutines to be able to call val childObj = parentObject.createChild( initParam ) without having to know about my allowed message types, or the actor system in general. eg, Not parentObject ! CreateChild( initParam ), and then handle a response received in another message.

I know I could hide the asynchronous responses behind Futures, but are there other known patterns for a synchronous system handing off computation to a hidden actor system?

(I realize that this will result in a blocking call into the library.)

1

There are 1 answers

1
Brian McCutchon On BEST ANSWER

Desktop app

A lot of things that apply to libraries also apply here, so look at the below section. If nothing else, you can wrap the part of your code that uses Akka as a separate library. One caveat is that, if you're using Swing, you will probably want to use SwingUtilities.invokeLater to get back on the Event Dispatch Thread prior to interacting with a GUI. (Also, don't block that thread. You probably want to use futures to avoid this, so consider designing your library to return futures.)

Library

Your example seems to assume a thin wrapper around your actors, or, at the very least, a bottom-up design where your interface is driven by your implementation details. Instead, design the library in a more top-down manner, first figuring out the library's interface, then (possibly) using Akka as an implementation detail. (This is a good idea for library design in general.) If you've already written something using Akka, don't worry, just design the interface separately from the implementation and stitch the two together. If you do this, you don't need a specific pattern, as the normal pattern of interface design apply regardless of the fact that you are using Akka.

As an example, consider a compiler. The compile method signature might be simple:

def compile(sources: List[File]): List[File]  // Returns a list of binaries

No mention of actors here. But this might do:

compileActor ? Compile(sources)

...and block on the result. The main compiler actor might depend on other actors, but there's no reason to expose those through the public API.