scalaakkaactorakka-typed

Akka: issue with Timer


I'm trying to create actor, which perform some action on timer. So I seek a way to schedule actor messages to self.

For this aim I use Behaviors.withTimers

object Consumer {
     sealed trait Command
     private object Timeout extends Command
     private case object TimerKey

     def apply(): Behavior[Command] = {
            Behaviors.withTimers(timers => new Consumer(timers).idle())
     }
  }

Method idle() must start sending messages Timeout to self in regular intervals.

  class Consumer(timers: TimerScheduler[Command]) {

       private def idle(): Behavior[Command] = {
           timers.startTimerWithFixedDelay(TimerKey, Timeout, FiniteDuration.apply(1, SECONDS))
           action()
           Behaviors.same
       }

       def action(): Behavior[Command] = {
             Behaviors.receiveMessage[Command] {
                case Timeout => println(" Consumer action done")
                Behaviors.same
         }
      }
    }

And action() must hook this messages against Behavior[Command]. But this is not happening. For some reasons, as I understand, timers not started. But what are that reasons?


Solution

  • The timers are being started and the Timeout message is being sent, but your Consumer actor isn't handling it, so the println never executes.

    Your apply injects timers into Consumer. In idle, you're starting the timer, then calling action to construct a new Behavior, but you then throw it away and actually use the same behavior your actor has (which won't respond to any messages).

    idle should probably be defined along these lines (I'm also using the duration DSL: import scala.concurrent.duration._)

    timers.startTimerWithFixedDelay(TimerKey, Timeout, 1.second)
    action()