Search code examples
scalaactor

Omitting all Scala Actor messages except the last


I want omit all the same type of messages except the last one:

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

for example when I send:

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

then I want to recevie only:

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

Of course if they will be send very fast, or on high CPU load


Solution

  • You could wait a very short amount of time, storing the most recent messages that arrive, and then process only those most recent ones. This can be accomplished by sending messages to yourself, and scheduleOnce. See the second example under the Akka HowTo: Common Patterns, Scheduling Periodic Messages. Instead of scheduling ticks whenever the last tick ends, you can wait until new messages arrive. Here's an example of something like that:

    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
    }
    

    Incoming Messages are not actually processed right away, but are stored in a Map that keeps only the last of each MessageType. On the ProcessNow tick message, they are really processed.

    You can change the length of time you wait (in my example set to 1 millisecond) to strike a balance between responsivity (length of time from a message arriving to response) and efficiency (CPU or other resources used or held up).