Scala / akka离散事件模拟

时间:2016-05-05 16:20:17

标签: scala testing akka simulation

我正在考虑将大型代码库迁移到Scala并利用Akka Actor模型。我几乎立即遇到了以下概念问题:

在现有代码库中,使用具有确定性结果的SimPy等离散事件模拟(DES)测试业务逻辑。虽然实时程序适用于hous,但DES需要几分钟。实时系统可以是异步的,不需要遵循测试设置的确切顺序。我想在测试设置和实时设置中使用相同的Akka代码。这可以在Scala + Akka中实现吗?

我已经玩弄了一个中央消息队列Actor的想法 - 但觉得这不是正确的方法。

1 个答案:

答案 0 :(得分:3)

解决您所述问题的一般方法是隔离您的业务逻辑"来自Akka代码。这允许业务代码进行单元测试和事件测试,独立于Akka,这也允许您编写非常精简的Akka代码。

举个例子,假设您的业务逻辑是处理一些Data

object BusinessLogic {
  type Data = ???
  type Result = ???

  def processData(data : Data) : Result = ???
}

这是一个干净的实现,可以在任何并发环境中运行,而不仅仅是Akka(Scala Futures,Java线程......)。

历史模拟

然后可以在离散事件模拟中运行核心业务逻辑:

import BusinessLogic.processData

val someDate : Date = ???

val historicData : Iterable[Data] = querySomeDatabase(someDate)

//discrete event simulation
val historicResults : Iterable[Result] = historicData map processData

如果并发能够使事件模拟器更快,那么就可以使用非Akka方法:

val concurrentHistoricResults : Future[Iterable[Result]] = 
  Future sequence {
    historicData.map(data => Future(processData(data)))
  }

Akka Realtime

同时逻辑可以合并到Akka Actors中。一般来说,将receive方法仅仅作为数据调度程序"非常有帮助,不应该存在于Actor定义中的任何实质性代码:

class BusinessActor extends Actor {

  override def receive = {
    case data : Data => sender ! processData(data)
  }
}

类似地,业务逻辑可以放在akka流中,用于反压流处理:

val dataSource : Source[Data, _] = ???

val resultSource : Source[Result, _] = 
  dataSource via (Flow[Data] map processData)