【问题标题】:How can I make this periodic metrics collection code more functional (less mutable state)?如何使此定期指标收集代码更具功能性(不可变状态)?
【发布时间】:2019-01-27 18:54:38
【问题描述】:

这是我的代码大纲

有多个工作人员参与者,我正在从他们那里收集一些延迟统计信息到 httpActorLatencies 映射中,其中每个工作人员参与者的延迟被单独跟踪,然后登录接收 LogQueueLatency 消息。此时httpActorLatencies中的所有队列也被清空。

有没有办法以合理的方式摆脱可变 Map ?

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

【问题讨论】:

  • 刚开始,更喜欢可变集合的 var 而不是可变集合的 val,因为 var 将保留在范围内并且不会通过消息泄漏给另一个参与者...stackoverflow.com/questions/11386559/… ;) 使用成为,正如蒂姆回答所建议的那样,您可以一起避免使用 var

标签: scala functional-programming akka


【解决方案1】:

一种方法是使用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 的需求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-26
    • 2018-02-16
    • 2022-09-25
    • 1970-01-01
    相关资源
    最近更新 更多