Created
September 7, 2013 21:42
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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