【发布时间】:2014-03-21 08:52:14
【问题描述】:
我正在尝试用 Scala 编写一个数据模块。
在并行加载整个数据时,一些数据依赖于其他数据,因此必须以有效的方式管理执行顺序。
例如在代码中,我保留了一张带有数据名称和清单的地图
val dataManifestMap = Map(
"foo" -> manifest[String],
"bar" -> manifest[Int],
"baz" -> manifest[Int],
"foobar" -> manifest[Set[String]], // need to be executed after "foo" and "bar" is ready
"foobarbaz" -> manifest[String], // need to be executed after "foobar" and "baz" is ready
)
这些数据将存储在可变哈希映射中
private var dataStorage = new mutable.HashMap[String, Future[Any]]()
有些代码会加载数据
def loadAllData(): Future[Unit] = {
Future.join(
(dataManifestMap map {
case (data, m) => loadData(data, m) } // function has all the string matching and loading stuff
).toSeq
)
}
def loadData[T](data: String, m: Manifest[T]): Future[Unit] = {
val d = data match {
case "foo" => Future.value("foo")
case "bar" => Future.value(3)
case "foobar" => // do something with dataStorage("foo") and dataStorage("bar")
... // and so forth (in a real example it would be much more complicated for sure)
}
d flatMap {
dVal => { this.synchronized { dataStorage(data) = dVal }; Future.value(Unit) }
}
}
这样,当“foo”和“bar”准备好时,我无法确保“foobar”已加载,等等。
由于我可能有数百个不同的数据,我该如何以“酷”的方式管理它?
如果我可以拥有某种数据结构,其中包含必须在某事之后加载某事的所有信息,并且顺序执行可以由 flatMap 以一种简洁的方式处理,那将是“很棒的”。
提前感谢您的帮助。
【问题讨论】:
-
可能在这里使用 Actors 会更有意义?
-
对不起,糟糕的 sudo 代码。此外,我需要确保在尝试加载“foobar”时“foo”和“bar”已准备就绪。所以解决方案不一定需要与Futures的顺序执行相关。它可以正确地使用 Promise,或者任何可以达到目的的东西。谢谢。
-
这正是有状态的参与者可以派上用场的地方。
-
@Ashalynd 谢谢你的建议!我仍然不确定我应该使用什么设计:)