2

嗨,我有一个 akka 演员:

public class StatusActor  extends UntypedActor {
public static ActorRef instance = Akka.system().actorOf(
        new Props(StatusActor.class));

public void onReceive(Object message) {
    Logger.info("Message received");
}

}

我每 5 分钟为它创建一个时间表:

Akka.system().scheduler().schedule(
        Duration.create(60, TimeUnit.SECONDS),
        Duration.create(5, TimeUnit.MINUTES), StatusActor.instance, null);

我遇到的问题是我想动态更改这个时间?有什么办法可以做到这一点吗?我找不到任何方法来阻止它。这样我就可以重新开始了。

我想到的唯一破解方法是在 onReceive 结束时让它调用 akka 计划重新开始,并将所有值更改为运行一次,并在 StatusActor 中有一个用于频率的静态变量。

如果有人能告诉我如何阻止演员/获得访问权,那将非常有帮助。

4

2 回答 2

2

如果您在 IDE 或文档中查看 schedule 的返回值,您会看到它返回一个 Cancellable,因此您可以取消前一个并安排一个新的。

希望有帮助!

干杯,√</p>

于 2012-06-19T11:42:23.293 回答
1

您需要执行的几个步骤:

1 你需要有一个全局键值变量。这里我使用 ConcurrentHashMap,因为普通的 HashMap 在多线程环境中是不安全的。

var schedulerIDs = new ConcurrentHashMap[String, Cancellable]().asScala

2 每次创建调度器时,都需要将其存储到键值变量中。您需要设计您的密钥,这里我使用调度程序的创建时间和创建此调度程序的用户作为密钥(只是因为它是唯一的,我很容易恢复它。)。它的值是它的可取消变量。(记住你不能阅读它的内容,因为它只是可取消的类型。)

val schedulerID = system.scheduler.schedule(initialDelay, interval, myActor, subMessage)

val schedulerKey = startTime + userName
val filterOption = schedulerIDs.get(schedulerKey)
filterOption match {
  case None =>
    schedulerIDs += schedulerKey -> schedulerID
  case _ =>
}

3 当你想修改一个调度器时,你需要从键值变量中获取它的信息来得到它的可取消变量。然后使用这个可取消变量先取消这个调度器,然后从这个键值变量中移除这个调度器。

def removeScheduler(createTime: String, userName: String) {
  val schedulerKey = createTime + userName
  val filterOption = schedulerIDs.get(schedulerKey)
  filterOption match {
    case None =>
    case Some(value) =>
      value.cancel()
      schedulerIDs.remove(schedulerKey)
  }
}

4 最后一步是创建一个新的调度程序,转到第 2 步并返回第 1 步进行存储。

此解决方案使用全局变量来存储调度程序信息。它的好处是快,但缺点是当服务器关闭时,所有这些信息都会消失。因为当服务器关闭时全局变量将消失。

所以通常我会在 Step1 中将调度程序信息一起存储到 DB 中,以根据其调度程序信息(如初始化时间、间隔等)恢复所有内容。就像创建新的调度程序一样。但用户或前端不会注意到它。

于 2015-12-11T14:43:52.017 回答