模拟时间和 Akka 调度程序

Simulating time and Akka schedulers

我正在使用 Akka 构建多代理模拟,因此希望 运行 比实时模拟更快。具体来说,我想配置 Akka 调度程序,以便调度程序从一个计划事件前进到下一个计划事件(这显然可能在事件之间涉及完全不同的时间步长),而不是按一些潜在的固定时间步前进。

换句话说,我希望调度程序表现得好像它是一种优先级队列,其中优先级由事件的模拟时间戳给出。

看清楚了吗?如果是这样,我想使用 Actor System 的默认调度程序可以做什么吗?如果这不可能,那么我将如何使用现有的 Akka 组件来滚动我自己的调度程序来完成此任务。

我认为 akka 调度程序不可能做到这一点。来自 documentation(强调我的):

Sometimes the need for making things happen in the future arises, and where do you go look then? Look no further than ActorSystem! There you find the scheduler method that returns an instance of akka.actor.Scheduler, this instance is unique per ActorSystem and is used internally for scheduling things to happen at specific points in time.

但是,您始终可以使用递归函数完成同样的事情。假设您的 "real time" 功能类似于:

def periodicFunction() : Unit = ???  //whatever you're doing to Agents

//periodicFunction is called every 10 seconds
actorSystem.scheduler().schedule(0 seconds, 10 seconds)(periodicFunction())

您的模拟代码可以是:

@scala.annotation.tailrec
def fasterThanRealTimeLoop(n : Int) = 
  if(n > 0) {
    periodicFunction()

    fasterThanRealTimeLoop(n-1)
  }

然后你可以用

模拟 20 次运行
fasterThanRealTimeLoop(20)

可以进一步包装此功能以封装两种可能性:

val realtimeMode : Boolean = ??? //some configuration setting

val periodicArgs : Either[FiniteDuration, Int] = 
  if(realtimeMode) Left(10 Seconds) else Right(20)

periodicArgs.left.foreach { period => 
  actorSystem.scheduler().schedule(0 seconds, period)(periodicFunction())
}

periodicArgs.right.foreach { count => 
  fasterThanRealTimeLoop(count)
}

此代码现在将调用正确类型的循环(定时或尽可能快),具体取决于配置设置。