Play中的全局可变参考对象,通过Actor进行交换

时间:2015-04-13 02:48:57

标签: scala playframework akka

我想创建一个具有可变引用的全局范围变量,但是使用不可变对象,例如

var globalMap = Map("a" -> 1, "b" -> c)

现在我希望能够在我的所有控制器中使用此globalMap,你怎么能在游戏中使用它?

我想创建一个将使用计时器的akka​​ actor,每隔x秒就会创建一个新的map,它将通过读取db来初始化,然后成为globalMap变量的新引用。

注意:我没有找人说这是糟糕的设计等等,我只是想了解这是否可行,以及如何在游戏中这样做。

2 个答案:

答案 0 :(得分:2)

为一组读者(线程,控制器,无关紧要)提供一些值可用,这要求您正确发布新值。第一部分是同步,以便最多只有一个更新同时运行,你可以通过使用Actor来解决这个问题(还有其他方法,但是一个Actor工作)。第二部分是在编写器和读者之间进行同步,这样他们只能看到正确初始化和一致的对象而不是一些随机垃圾。幸运的是,JVM具有相当明确的内存模型,因此唯一需要的是将变量标记为@volatile

对于替代实现,您可能需要检查此问题的预打包解决方案,例如Akka Agents

import akka.agent.Agent

object MyGlobal {
  val theMap = Agent(Map.empty[String, Int])
}

然后你的更新程序(如果你想方便地安排事情,可能仍然是一个Actor,但现在可以是代码的任何部分)只需使用send(或alter如果你需要知道什么时候读者使用get获取当前值时更新值。

答案 1 :(得分:0)

与没有Play的情况一样。把它放在一个对象MapHolder中。使用

从特征继承控制器
def globalMap = MapHolder.globalMap

这太容易了......你还需要更多东西吗?