Scala / akka离散事件模拟 [英] Scala/akka discrete event simulation

查看:107
本文介绍了Scala / akka离散事件模拟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am considering migrating a large code base to Scala and leveraging the Akka Actor model. I am running into the following conceptual issue almost immediately:

在现有代码库中,使用离散事件模拟(DES)(例如SimPy)对具有确定性结果的业务逻辑进行了测试。当实时程序运行时,DES需要花费几分钟。实时系统可以是异步的,不需要遵循测试设置的确切顺序。我想在测试设置和实时设置中使用相同的Akka代码。这样可以在Scala + Akka中实现吗?

In the existing code base, business logic is tested using a discrete event simulation (DES) like SimPy with deterministic results. While the real-time program runs for hous, the DES takes a few minutes. The real time system can be asynchronous and need not follow the exact ordering of the testing setup. I'd like to leverage the same Akka code for both the testing setup and the real-time setup. Can this be achieved in Scala + Akka?

我很喜欢中央消息队列Actor的想法-但觉得这不是正确的方法。

I have toyed with the idea of a central message queue Actor -- but feel this is not the correct approach.

推荐答案

解决您提出的问题的通用方法是将业务逻辑与Akka代码隔离开。这样就可以独立于Akka进行业务代码的单元测试和事件测试,这还使您可以编写非常精简的Akka代码。

A general approach to solving the problem you stated is to isolate your "business logic" from Akka code. This allows the business code to be unit tested, and event tested, independently of Akka which also allows you to write very lean Akka code.

例如,假设您业务逻辑是处理某些数据

As an example, say you're business logic is to process some Data:

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

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

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

This is a clean implementation that can be run in any concurrency environment, not just Akka (Scala Futures, Java threads, ...).

历史模拟

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

The core business logic can then be run in your discrete event simulation:

import BusinessLogic.processData

val someDate : Date = ???

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

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

如果并发能够使事件模拟器更快,则可以使用非Akka方法: / p>

If concurrency is capable of making the event simulator faster then it is possible to use a non-Akka approach:

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

Akka实时

与此同时,逻辑可以合并到Akka Actors中。通常,使您的 receive 方法无非是一个数据分配器,这非常有帮助,Actor定义中不应包含任何实质性代码:

At the same time the logic can be incorporated into Akka Actors. In general it is very helpful to make your receive method nothing more than a "data dispatcher", there shouldn't be any substantive code residing in the Actor definition:

class BusinessActor extends Actor {

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

类似地,可以放置业务逻辑在akka流内部进行反压流处理:

Similarly the business logic can be placed inside of akka streams for back-pressured stream processing:

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

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

这篇关于Scala / akka离散事件模拟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆