Scala/akka discrete event simulation

牧云@^-^@ 提交于 2019-12-11 13:52:54

问题


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:

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?

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


回答1:


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 = ???
}

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

Historic Simulation

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

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 Realtime

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)
  }
}

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)


来源:https://stackoverflow.com/questions/37055472/scala-akka-discrete-event-simulation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!