节流仅保留最新消息的akka​​-actor

时间:2019-03-26 16:00:19

标签: scala akka throttling akka-actor

情况

我正在使用Akka演员来更新Web客户端上的数据。这些参与者之一仅负责发送有关单个Agent的更新。这些代理会非常快速地更新(每10毫秒一次)。我现在的目标是限制这种更新机制,以使每Agent的最新版本每300毫秒发送一次。

我的代码

这是我到目前为止提出的:

/**
  * Single agents are updated very rapidly. To limit the burden on the web-frontend, we throttle the messages here.
  */
class BroadcastSingleAgentActor extends Actor {

    private implicit val ec: ExecutionContextExecutor = context.dispatcher
    private var queue = Set[Agent]()

    context.system.scheduler.schedule(0 seconds, 300 milliseconds) {
        queue.foreach { a =>
            broadcastAgent(self)(a) // sends the message to all connected clients
        }
        queue = Set()
    }

    override def receive: Receive = {
        // this message is received every 10 ms for every agent present
        case BroadcastAgent(agent) => 
           // only keep the newest version of the agent
           queue = queue.filter(_.id != agent.id) + agent
    }

}

问题

此actor(BroadcastSingleAgentActor)可以正常工作,但是我不确定100%是否安全(在清除queue的同时更新Agent)。另外,这并不意味着我在充分利用akka提供给我的工具中发挥最大的作用。我找到了此article(Akka 2中的节流消息),但是我的问题是我需要保留最新的login() { return this.http.post<Users>(base_url + 'login.json',{ email: user.username, password: user.password }).pipe( catchError(() => {}) // do something if error ) } 消息,同时删除任何旧版本。是否有类似我所需要的示例?

1 个答案:

答案 0 :(得分:1)

否,这不是线程安全的,因为通过ActorSystem进行的调度将发生在receive之外的另一个线程上。一种可能的想法是在receive方法内进行调度,因为到BroadcastSingleAgentActor的传入消息将被顺序处理。

  override def receive: Receive = {

    case Refresh =>
      context.system.scheduler.schedule(0 seconds, 300 milliseconds) {
        queue.foreach { a =>
          broadcastAgent(self)(a) // sends the message to all connected clients
        }
      }
      queue = Set()
    // this message is received every 10 ms for every agent present
    case BroadcastAgent(agent) =>
      // only keep the newest version of the agent
      queue = queue.filter(_.id != agent.id) + agent
  }