使Scala远程演员更稳定
我正在编写一个小测试程序来尝试使用我在
Scala项目中需要的Remote Actors.
基本目标是编写一个服务器的测试应用程序,该服务器可以处理一堆客户端和可以同时发送多个消息的更重要的客户端(如ping,更新请求和用户引发的数据请求) 我想出的是: import scala.actors.remote.RemoteActor import scala.actors.remote.Node import scala.actors.Actor trait Request trait Response case object WhoAmI extends Request case class YouAre(s:String) extends Response case object Ping extends Request case object Pong extends Response case class PrintThis(s:String) extends Request case object PrintingDone extends Response object Server { def main(args: Array[String]) { val server = new Server server.start } } class Server extends Actor { RemoteActor.alive(12345) RemoteActor.register('server,this) var count:Int = 0 def act() { while(true) { receive { case WhoAmI => { count += 1 sender ! YouAre(count.toString) } case Ping => sender ! Pong case PrintThis(s) => { println(s) sender ! PrintingDone } case x => println("Got a bad request: " + x) } } } } object Act3 extends scala.actors.Actor { def act = { var i = 0 Thread.sleep(900) while (i <= 12) { i += 1 val a = new Printer a.start Thread.sleep(900) } } } class Printer extends scala.actors.Actor { def act = { val server = RemoteActor.select(Node("localhost",12345),'server) server ! PrintThis("gagagagagagagagagagagagaga") receive { case PrintingDone => println("yeah I printed") case _ => println("got something bad from printing") } } } object Act2 extends scala.actors.Actor { def act = { var i = 0 while (i < 10) { i+=1 val a = new Pinger a.start Thread.sleep(700) } } } class Pinger extends scala.actors.Actor { def act = { val server = RemoteActor.select(Node("localhost",'server) server ! Ping receive { case Pong => println("so I pinged and it fits") case x => println("something wrong with ping. Got " + x) } } } object Act extends scala.actors.Actor { def act = { var i = 0 while(i < 10) { i+=1 val a = new SayHi a.start() Thread.sleep(200) } } } class SayHi extends scala.actors.Actor { def act = { val server = RemoteActor.select(Node("localhost",'server) server ! "Hey!" } } object Client { def main(args: Array[String]) { Act.start() //Act2.start() Act3.start() } } 问题是,事情并没有像我期望的那样顺利运行: 这可能不是最大的问题,但它们足以让我感到非常不舒服.我在演员和远程演员上做了很多阅读,但我发现可用的信息相当缺乏. 试图在任何看似合适的地方添加退出声明.但这没有帮助. 有谁知道我做错了什么?这里有任何一般技巧吗?一些dos和donts? 解决方法
我的猜测是你的问题源于使用receive和Thread.sleep来阻止你的actor的线程.阻塞操作会占用actor的线程池中的线程,这可能会阻止其他actor执行,直到将新线程添加到池中.
This question可能会提供一些额外的见解.
您可以使用loop,loopWhile,react和reactWithin来重写许多actor以使用非阻塞操作.例如 import scala.actors.TIMEOUT object Act extends scala.actors.Actor { def act = { var i = 0 loopWhile(i < 10) { reactWithin(200) { case TIMEOUT => i+=1 val a = new SayHi a.start() } } } } 当然,您可以通过编写自己的控件构造来消除一些样板: def doWithin(msec: Long)(f: => Unit) = reactWithin(msec) { case TIMEOUT => f } def repeat(times: Int)(f: => Unit) = { var i = 0 loopWhile(i < times) { f i+=1 } } 这将允许你写 repeat(10) { doWithin(200) { (new SayHi).start } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |