下面是我的代码的概要
有多个工作者参与者,我从他们那里收集一些延迟统计数据到httpActorLatencies
映射中,其中每个工作者参与者的延迟被单独跟踪,然后登录接收LogQueueLatency
消息。此时,httpActorLatencies
中的所有队列也将被清除。
有没有办法以一种合理的方式摆脱可变映射?
class StatsActor(workerCount: Int) extends Actor {
val httpActorLatencies = scala.collection.mutable.Map[Int, scala.collection.mutable.MutableList[Long]]()
override def preStart(): Unit = {
Range(0, workerCount).foreach(i => httpActorLatencies.put(i, scala.collection.mutable.MutableList()))
}
override def receive = {
case shardLatency: QueuingLatency =>
httpActorLatencies(shardLatency.shardNumber) += shardLatency.latency
case LogQueueLatency =>
outputCollectedStats()
}
private def outputCollectedStats(): Unit = {
output(StatsActor.computePerShardMeanLatencies(httpActorLatencies))
httpActorLatencies.foreach(x => x._2.clear())
}
}
发布于 2018-08-21 15:24:00
一种方法是使用context.become
和一个带有Map
的接收函数,如下所示:
class StatsActor extends Actor {
def newMap() = Map[Int, List[Long]]().withDefault(Nil)
def receive: Receive = countingReceive(newMap())
def countingReceive(httpActorLatencies: Map[Int, List[Long]]): Receive = {
case shardLatency: QueuingLatency =>
val newList = httpActorLatencies(shardLatency.shardNumber) :+ shardLatency.latency
val newMap = httpActorLatencies.updated(shardLatency.shardNumber, newList)
context.become(countingReceive(newMap))
case LogQueueLatency =>
outputCollectedStats(httpActorLatencies)
context.become(receive)
}
private def outputCollectedStats(httpActorLatencies: Map[Int, List[Long]]): Unit = {
...
}
}
这是未经测试的,而且可能是坏的,但它应该给出一个可能如何完成的想法。
还要注意,我在Map
上使用了withDefault
,以简化逻辑并消除对workerCount
的需要。
https://stackoverflow.com/questions/51951151
复制