Skip to content

Instantly share code, notes, and snippets.

@viktorklang
Created September 7, 2013 21:42
Show Gist options
  • Save viktorklang/6479579 to your computer and use it in GitHub Desktop.
Save viktorklang/6479579 to your computer and use it in GitHub Desktop.
Creates an ExecutionContext inside an Actor that will execute the runnables inside the Actor receive block, so that the risk of closing over Actor internals is less problematic.
//Warning: Uses Akka internal APIs (not binary compatible),
//can be written not to depend on that but implemented like this for brevity.
package akka.util
trait CallbackExecutionContext { this: akka.actor.Actor ⇒
// Defines our signal for callback execution
case object Execute
// ``SerializedSuspendableExecutionContext`` is Akka-internal
private[this] final val ssec: SerializedSuspendableExecutionContext = {
val d = this.context.dispatcher
val s = this.self
// The ``5`` is the throughput setting for the EC, e.g. the number of callbacks that will be
// executed per sweep, the parametrization of this is left as an exercise for the reader.
SerializedSuspendableExecutionContext(5 /*Chosen by fair dice roll*/)(new ExecutionContext {
override def execute(runnable: Runnable) = s ! Execute
override def reportFailure(t: Throwable) = d reportFailure t
})
}
// This is the ``ExecutionContext`` that you'll use
final def callbackExecutionContext: ExecutionContext = ssec
// Must be used in the extending Actor's ``receive`` definition
def handleCallbacks: Receive = {
case Execute ⇒ ssec.run()
}
}
// Contrived example
class Foo extends Actor with CallbackExecutionContext {
var mutable = 0
def receive = handleCallbacks orElse {
case "pigdog" =>
implicit val ec = callbackExecutionContext
Future { if(mutable == 0) "Foo" else "Bar" } map { _.toUpperCase } map {
case "FOO" => mutable = 1
case "BAR" => mutable = 0
} foreach { _ => println("Current mutable: " + mutable)}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment