窥视Scala演员邮箱的最佳方法 [英] Best method to peek into a Scala Actor's Mailbox

查看:54
本文介绍了窥视Scala演员邮箱的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Scala 2.8 RC1或更高版本,什么是最好的(最简单和/或最直接的)方法(从同一actor的act()方法中)窥视 actor邮箱中的等待消息?队列中的内容,而不必以任何方式响应/接收消息和/或干扰邮箱的当前内容。

Using Scala 2.8 RC1 or newer, what is the best (easiest and/or most direct) method to "peek" at the waiting messages in an actor's mailbox (from within the same actor's act() method) in order to examine what is in the queue, without having to react/receive the messages and/or disturb the current contents of the mailbox in any way.

参与者可以通过首先确定是否有剩余的邮箱消息是必须处理的消息来确定处理退出请求是否安全,而不是通过立即停止参与者来丢弃它。

The purpose of this is so that an actor may determine if it is safe to process a request to exit by first determining if any of the remaining mailbox messages are ones that must be processed, instead of just dropped by stopping the actor immediately.

推荐答案

您无需先窥视。只需跟踪已请求退出的事实,并使用reactWithin(0)确定在请求退出后队列何时为空。

You don't need to peek ahead. Just keep track of the fact that an exit has been requested and use a reactWithin(0) to determine when the queue is empty after an exit has been requested.

import scala.actors._

sealed case class Message
case object Exit extends Message
case class Unimportant(n:Int) extends Message
case class Important(n:Int) extends Message

class SafeExitingActor extends Actor {
  def act : Nothing = react {
      case Exit => {
           println("exit requested, clearing the queue")
           exitRequested
      }
      case message => {
           processMessage(message, false)
           act
      }
  }

  // reactWithin(0) gives a TIMEOUT as soon as the mailbox is empty
  def exitRequested : Nothing = reactWithin(0) {
     case Exit => {
         println("extra exit requested, ignoring")
         exitRequested // already know about the exit, keep processing
     }
     case TIMEOUT => {
         println("timeout, queue is empty, shutting down")
         exit // TIMEOUT so nothing more to process, we can shut down
     }
     case message => {
         processMessage(message, true)
         exitRequested
     }
  }

  // process is a separate method to avoid duplicating in act and exitRequested
  def processMessage(message : Any, importantOnly : Boolean) = {
     message match {
       case Unimportant(n) if !importantOnly => println("Unimportant " + n)
       case Unimportant(n) => () // do nothing
       case Important(n) => println("Important! " + n)
     }
     Thread sleep 100 // sleep a little to ensure mailbox backlog
  }
}

object TestProcessing {
  def main(args : Array[String]) {
    val actor = new SafeExitingActor()
    actor.start()
    for (i <- 1 to 10) {
        actor ! Unimportant(i)
        actor ! Important(i)
    }
    actor ! Exit
    for (i <- 11 to 20) {
        actor ! Unimportant(i)
        actor ! Important(i)
    }
    actor ! Exit
    actor ! Important(100)
  }
}

应该输出

Unimportant 1
Important! 1
Unimportant 2
Important! 2
Unimportant 3
Important! 3
Unimportant 4
Important! 4
Unimportant 5
Important! 5
Unimportant 6
Important! 6
Unimportant 7
Important! 7
Unimportant 8
Important! 8
Unimportant 9
Important! 9
Unimportant 10
Important! 10
exit requested, clearing the queue
Important! 11
Important! 12
Important! 13
Important! 14
Important! 15
Important! 16
Important! 17
Important! 18
Important! 19
Important! 20
extra exit requested, ignoring
Important! 100
timeout, queue is empty, shutting down

这篇关于窥视Scala演员邮箱的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆