一定時間ごとに何かする Actor

普通に書くと、sleepしている間は何もできなくなるし、
コップ本にもブロックするなと書いてあったので、
ヘルパーActorを使って書いてみた。

import scala.actors.Actor
import scala.actors.Actor._

def makeTimerActor(func: => Any) = actor {
                      var validID = ""
                    
                      def timeoutActor(id:String, timeout:Int, act:Actor) = actor {
                        func
                        Thread.sleep(timeout)
                        act ! ("timeout", id, timeout)
                      }
                      
                      loop {
                        react {
                          case ("start", t:Int) =>
                            validID = java.util.UUID.randomUUID.toString
                            timeoutActor(validID, t, self)
                            println("start:" + validID)
                          case "stop" =>
                            validID = ""
                          case ("timeout", id:String, t:Int) =>
                            if (id == validID)
                              timeoutActor(id, t, self)
                            else
                              println("stop:"  + id)
                          case _ =>
                            // UNKNOWN
                        }
                      }
                    }

かんたんな、使い方は、

scala> val timer = makeTimerActor{
  println("start TASK...")
  println(new java.util.Date)
}

scala> timer ! ("start", 10000)

scala> start:47eed3c9-dcac-45aa-9275-84ea4e3cdd58
start TASK...
Sun Jan 10 23:06:36 JST 2010
start TASK...
Sun Jan 10 23:06:46 JST 2010


scala> timer ! "stop"          

scala> stop:47eed3c9-dcac-45aa-9275-84ea4e3cdd58

連続してstartした場合には、後からの指令が有効になる。

scala> timer ! ("start", 10000)

scala> start:c65e0542-722d-4137-83e8-c2e9798d24cb
start TASK...
Sun Jan 10 23:19:41 JST 2010


scala> timer ! ("start", 10000)

scala> start:52ab9656-9f22-4df5-84fc-4ca987ba12da
start TASK...
Sun Jan 10 23:19:47 JST 2010
stop:c65e0542-722d-4137-83e8-c2e9798d24cb
start TASK...
Sun Jan 10 23:19:57 JST 2010
start TASK...
Sun Jan 10 23:20:07 JST 2010


scala> timer ! "stop"               

scala> stop:52ab9656-9f22-4df5-84fc-4ca987ba12da