省略除最后一个之外的所有Scala Actor消息

时间:2014-07-03 16:09:19

标签: scala actor

我想省略除最后一条之外的所有相同类型的消息:

def receive =  {
   case Message(type:MessageType, data:Int) =>
     // remove previous and get only last message of passed MessageType
}

例如我发送时:

actor ! Message(MessageType.RUN, 1)
actor ! Message(MessageType.RUN, 2)
actor ! Message(MessageType.FLY, 1)

然后我只想接收:

Message(MessageType.RUN, 2)
Message(MessageType.FLY, 1)

当然,如果它们发送得非常快,或者CPU负载很高

2 个答案:

答案 0 :(得分:3)

您可以等待很短的时间,存储到达的最新消息,然后只处理最近的消息。这可以通过向您自己发送消息来完成,scheduleOnce。请参阅the Akka HowTo: Common Patterns, Scheduling Periodic Messages下的第二个示例。您可以等到新消息到达时,而不是在最后一个节拍结束时安排节拍。这是一个类似的例子:

case class ProcessThis(msg: Message)
case object ProcessNow

var onHold = Map.empty[MessageType, Message]
var timer: Option[Cancellable] = None

def receive = {
  case msg @ Message(t, _) =>
    onHold += t -> msg
    if (timer.isEmpty) {
      import context.dispatcher
      timer = Some(context.system.scheduler.scheduleOnce(1 millis, self, ProcessNow))
    }
  case ProcessNow =>
    timer foreach { _.cancel() }
    timer = None
    for (m <- onHold.values) self ! ProcessThis(m)
    onHold = Map.empty
  case ProcessThis(Message(t, data)) =>
    // really process the message
}

传入的Message实际上并未立即处理,而是存储在仅保留每个Map的最后一个的MessageType中。在ProcessNow刻度消息上,它们确实已被处理。

您可以更改等待的时间长度(在我的示例中设置为1毫秒),以在响应度(从消息到达响应的时间长度)和效率(CPU或其他使用或保留的资源)之间取得平衡

答案 1 :(得分:0)

type不是字段的好名称,因此请改用messageType。这段代码应该做你想要的:

var lastMessage: Option[Message] = None

def receive =  {
  case m => {
    if (lastMessage.fold(false)(_.messageType != m.messageType)) {
      // do something with lastMessage.get
    }
    lastMessage = Some(m)
  }
}