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?
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()