I came across this code and wonder what CallingThreadDispatcher
does.
I can comment out
val dispatcherId = CallingThreadDispatcher.Id
val props = Props[Greeter].withDispatcher(dispatcherId)
and the test will still work
class GreeterTest extends TestKit(testSystem)
with WordSpecLike
with MustMatchers
with StopSystemAfterAll {
"The Greeter" must {
"say Hello World! when a Greeting(\"World\") is sent to it" in {
val dispatcherId = CallingThreadDispatcher.Id
val props = Props[Greeter].withDispatcher(dispatcherId)
val greeter = system.actorOf(props)
EventFilter.info(message = "Hello World!", occurrences = 1).intercept {
greeter ! Greeting("World")
}
}
}
}
object GreeterTest {
val testSystem = {
val config = ConfigFactory.parseString("""akka.loggers = [akka.testkit.TestEventListener]""")
ActorSystem("testSystem", config)
}
}
The official documentation is really explanatory and extensive, enjoy:
docs
API
I actually did looked at the docs before I asked this question. I couldn’t
understand the docs hence looking for help with some other more layman
explanation
Ok, I thought that would be explanatory, but anyway…
whenever you create actors in akka, their internal message handling is processed by “lending” a thread from some executor, or more specifically, some dispatcher (the latter is a sort of wrapper of the actual executor used from the toolkit).
If you don’t specify the dispatcher on which actors “run”, the system will use a default one (in this case a forkjoin-pool based dispatcher). This usually means that actors execute their logic in a non-deterministic way, because the interaction depends on the sequence of the thread executions, which is affected by many different factors, and by the order that each actor’s message is received.
To create a stable test suite, that deterministically yields a successful or failed test, the akka toolkit provides the CallingThreadDispatcher
. If you specify that an actor should run with this dispatcher, it’s message handling is always executed on the thread that sent the message to the actor.
In practice, the Greeting
message received and handled on the same thread that runs the test.
When you comment out the specific dispatcher use in the tests, what happens is that the greeter
message handling will be performed on the ActorSystem
default forkjoin pool, instead of the test one.
1 Like
Thank you for taking time to explain this