Я писал небольшую тестовую программу, чтобы опробовать некоторые вещи с удаленными актерами, которые мне понадобятся в проекте Scala.
Основная цель состояла в том, чтобы написать тестовое приложение для одного сервера, которое могло бы обрабатывать группу клиентов и более важных клиентов, которые могут отправлять несколько сообщений одновременно (например, пинги, запросы на обновления и запросы пользователей на данные)
Я придумал вот что:
краткий обзор: клиент запускает 3 разных актера, которые снова запускают актеров в циклах while с разными смещениями для имитации довольно случайных сообщений.
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()
}
}
Проблема в том, что дела идут не так гладко, как я ожидал:
когда я начинаю только одного из действующих лиц клиента (комментируя других, как я делал с Act2
в Client
), обычно, но не всегда, все идет хорошо. Если я начинаю двух или более актеров, довольно часто распечатки появляются в большом количестве (то есть: ничего не происходит сразу, а затем распечатки появляются довольно быстро). Также клиент иногда завершает работу, а иногда нет.
Возможно, это не самые большие проблемы, но их достаточно, чтобы я чувствовал себя довольно неловко. Я много читал об актерах и удаленных актерах, но мне не хватает доступной информации.
Пытался добавить exit
операторов там, где это казалось подходящим. Но это не помогло.
Кто-нибудь понял, что я делаю не так? Есть какие-нибудь общие хитрости здесь? Какие-нибудь плюсы и минусы?