其他演员阅读时伴随对象变量更新

时间:2016-03-23 13:03:04

标签: multithreading scala akka

我们正在使用spray和akka构建REST。为此,我们需要从磁盘读取超过10k个文件(大多数是静态的,每天可能会有两次更新)。从磁盘读取每个请求都会给性能带来影响,我们将所有必需的信息放在DataMap(Map对象)中。使用akka调度程序每15分钟更新一次DataMap(需要使用最新的磁盘数据)。

class SampleScheduler extends Actor with  ActorLogging {
import context._
 val tick = context.system.scheduler.schedule(1.second,15.minute, self,"mytick")
override def postStop() = tick.cancel()
override def receive: Receive = {
case "mytick" => {
  println(s"Yes got the tick now ${new Date().toGMTString}")
  Test.setDataMap()
  }
 }
}

object Test {
var DataMap:Map[String,List[String]]=Map()
def setDataMap()={
  DataMap = //Read files from disk
 }
}

object Main extends App {
//For each new request look into DataMap
if(Test.DataMap.isEmpty) {
  //How to handle this, can i use like this
  Thread.sleep(1000)
 }
}

因此,当新请求到来时,它会从地图中搜索所需数据并获取信息,并相应地处理。

如何通过上述设计达到以下要求。

  1. 现在为每个请求创建一个actor并在DataMap上面读取并开始处理。开始处理后,如果DataMap变空并重新加载,如何处理?
  2. 如果DataMap发现空,如何重试?我可以使用Thread.sleep方法吗?
  3. 在“对象”的良好实践中,每隔15分钟存储一次DataMap并重置它吗?

1 个答案:

答案 0 :(得分:0)

首先,最重要的是,你必须避免(3)。在演员之外存储状态是邪恶的!此外,存储状态和维护状态是演员擅长的。

在将状态置于actor之后并通过消息分享之后,(2)将过时。请求actor会询问州演员,如果州演员忙于重新读取文件,它将在完成工作后回答。

最后,您可以遵循两种不同的策略来解决(1)。州议员将按顺序处理每条消息,以便它可以(a)回复具有最后知道状态的消息,或者(b)保留消息并回复新填充的状态,如果它认为它应该重新读取文件。