加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

使Scala远程演员更稳定

发布时间:2020-12-16 10:01:30 所属栏目:安全 来源:网络整理
导读:我正在编写一个小测试程序来尝试使用我在 Scala项目中需要的Remote Actors. 基本目标是编写一个服务器的测试应用程序,该服务器可以处理一堆客户端和可以同时发送多个消息的更重要的客户端(如ping,更新请求和用户引发的数据请求) 我想出的是: 简要概述:客户
我正在编写一个小测试程序来尝试使用我在 Scala项目中需要的Remote Actors.

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

我想出的是:
简要概述:客户端启动3个不同的actor,这些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",'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()
  }
}

问题是,事情并没有像我期望的那样顺利运行:
当我只启动其中一个客户端演员时(通过使用Act2in Client对其他演员进行评论)通常但并不总是顺利.如果我开始两个或更多演员,通常打印输出大量出现(意思是:没有任何事情一次发生,然后打印输出显得相当快).客户端有时会终止,有时也不会终止.

这可能不是最大的问题,但它们足以让我感到非常不舒服.我在演员和远程演员上做了很多阅读,但我发现可用的信息相当缺乏.

试图在任何看似合适的地方添加退出声明.但这没有帮助.

有谁知道我做错了什么?这里有任何一般技巧吗?一些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
   }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读