繁体   English   中英

如何在不使用var的情况下实现自动取消轮询?

[英]How to implement a self-cancelling poller without using a var?

我很好奇是否可以安全地实现自动取消轮询器而不使用var来保持akka.actor.Cancellable的实例

到目前为止,我提出了类似于下面示例中所示的内容。 但是, 我很好奇是否可以安全地假设在hotswap发生之前永远不会调度“tick”消息 ,即调度轮询器的行:

tick(1, 5, context.system.scheduler.schedule(Duration.Zero, 3 seconds, self, "tick"))

基本相同:

val poll = context.system.scheduler.schedule(Duration.Zero, 3 seconds, self, "tick")
tick(1, 5, poll)

所以,我认为在某些情况下,在热交换有机会发生之前会收到第一个滴答声......思考?

import akka.actor.{Cancellable, ActorSystem}
import akka.actor.ActorDSL._
import concurrent.duration._

object PollerDemo {
  def run() {
    implicit val system = ActorSystem("DemoPoller")
    import system.dispatcher

    actor(new Act{
      become {
        case "tick" => println("UH-OH!")
        case "start" =>
          become {
            tick(1, 5, context.system.scheduler.schedule(Duration.Zero, 3 seconds, self, "tick"))
          }
      }
      def tick(curr:Long, max:Long, poll:Cancellable):Receive = {
        case "tick" => {
          println(s"poll $curr/$max")
          if(curr > max)
            cancel(poll)
          else
            become{ tick(curr + 1, max, poll) }
        }
      }
      def cancel(poll:Cancellable) {
        println("cancelling")
        poll.cancel()
        println(s"cancelled successfully? ${poll.isCancelled}")
        println("shutting down")
        context.system.shutdown()
      }
    }) ! "start"

    system.awaitTermination(1 minute)
  }
}

我的猜测是你的代码没问题。 请记住,演员一次只能处理一个邮箱。 当您收到start消息时,您设置了一个计时器,它将向邮箱传递另一条消息,然后您交换接收实现。 因为在处理start消息时执行接收交换,所以在处理邮箱中的下一条消息之前,您已经更改了actor的接收行为。 因此,当它继续处理tick消息时,您可以确定它将使用新的接收行为。

你可以通过发送一个额外的验证此tick内的第一条消息become像这样:

become {
  self ! "tick"
  tick(1, 5, context.system.scheduler.schedule(Duration.Zero, 3 seconds, self, "tick"))
}

这里我们确实从等式中消除了计时器,当询问在成为块期间发送的消息是否将由旧接收或新接收处理时。 我没有运行这个,但根据我的理解或akka,这两个滴答应该由新的接收处理。

你真的不能用演员做纯函数式编程。 发送消息是一种副作用。 由于它们的接收函数不返回结果,所有演员在接收消息时都可以做到副作用。 几乎你的代码所做的每一件事都是副作用

您可能在代码实现中避免使用变量,但是become在Actor超类中变量变量。 context.system.scheduler.schedule显然是副作用并在某处改变状态。 cancel每一件事都是副作用。 system.awaitTermination(1 minute)不是函数...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM