我正在考虑将大型代码库迁移到Scala并利用Akka Actor模型。我几乎立即遇到了以下概念问题:
在现有代码库中,使用具有确定性结果的SimPy等离散事件模拟(DES)测试业务逻辑。虽然实时程序适用于hous,但DES需要几分钟。实时系统可以是异步的,不需要遵循测试设置的确切顺序。我想在测试设置和实时设置中使用相同的Akka代码。这可以在Scala + Akka中实现吗?
我已经玩弄了一个中央消息队列Actor的想法 - 但觉得这不是正确的方法。
答案 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)