一定時間ごとに何かする 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