gpt4 book ai didi

scala - 使 Scala Remote Actors 更加稳定

转载 作者:行者123 更新时间:2023-12-01 01:32:11 25 4
gpt4 key购买 nike

我正在编写一个小测试程序来尝试一些我在 Scala 项目中需要的远程 Actor 的东西。

基本目标是编写一个服务器的测试应用程序,该应用程序可以处理一堆客户端和更重要的客户端,可以同时发送多条消息(如 ping、更新请求和用户引发的数据请求)

我想出的是这样的:
简要概述:客户端启动 3 个不同的 Actor,它们再次在具有不同偏移量的 while 循环中启动 Actor,以模拟相当随机的消息。

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",12345), '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",12345), 'server)
server ! "Hey!"
}
}

object Client {
def main(args: Array[String]) {
Act.start()
//Act2.start()
Act3.start()
}
}

问题是事情并不像我期望的那样顺利:
当我只开始一个客户 Actor 时(通过评论其他人,就像我在 Act2 中对 Client 所做的那样),事情通常但并不总是顺利。如果我开始两个或更多 Actor ,打印输出通常会成批出现(意思是:没有任何事情同时发生,然后打印输出显示得相当快)。此外,客户端有时会终止,有时不会。

这可能不是最大的问题,但它们足以让我感到很不舒服。我阅读了大量关于 Actors 和 Remote Actors 的文章,但我发现可用的信息相当缺乏。

尝试添加 exit任何看起来合适的声明。但这没有帮助。

有没有人知道我做错了什么?这里有什么通用技巧吗?一些注意事项?

最佳答案

我的猜测是您的问题源于使用 receive 阻塞了 Actor 的线程。和 Thread.sleep .阻塞操作会消耗 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
}
}

关于scala - 使 Scala Remote Actors 更加稳定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4079568/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com