When using the methods on the default Akka system scheduler (context().system().scheduler().schedule()
from inside an actor), and one of the overloads accepting a destination actor, do I need to explicitly cancel using the returned Cancellable to free up resources when the destination actor stops?
I imagine the scheduler may be watch()
ing the destination actor and automatically perform the cleanup but cannot find it explicitly state anywhere in the documentation.
The variants of Scheduler.schedule
which take an ActorRef
will not watch that actor (which would have a rather high overhead relative to what a timer task is), hence you should always clean up the recurring timer from the actor’s postStop
hook.
In the local case we check target.isTerminated
, but that method always returns false
for actor references which are not of the bog-standard local kind, hence you can rely on this feature only in specific cases and your code would then stop working correctly when you scale out your application. Another consideration is that the aforementioned check runs when trying to send the message, which can be a “soft leak” (i.e. deferred cleanup) in case of long schedules (where depending on the use-case 100ms can already be long).
It looks like the task still runs, and the message more than likely ends up going to dead letter. You can see that behavior with the following code sample:
import akka.actor._
import scala.concurrent.duration._
object SchedTest {
def main(args: Array[String]) {
val sys = ActorSystem("test")
val ref = sys.actorOf(Props[MyActor])
val can = sys.scheduler.schedule(1 second, 1 second){
println("executing")
ref ! "foo"
}(sys.dispatcher)
Thread.sleep(10000)
sys.stop(ref)
Thread.sleep(5000)
can.cancel
}
}
class MyActor extends Actor{
def receive = {
case _ =>
println("received message...")
}
}
After 10 seconds, you will stop seeing the "received message..." string get printed, but you will continue to see the "executing" string get printed. Then after I manually kill the task, you stop seeing "executed" getting printed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With