배우가 한 번에 하나의 메시지를 처리합니다. 여러 메시지를 처리하는 고전적인 패턴은 소비자 행위자 풀에 대해 하나의 코디네이터 액터를 배치하는 것입니다. react를 사용하면 소비자 풀은 클 수 있지만 여전히 적은 수의 JVM 스레드 만 사용합니다. 여기에 10 명의 소비자 풀과 하나의 코디네이터를 만드는 예가 있습니다.
import scala.actors.Actor
import scala.actors.Actor._
case class Request(sender : Actor, payload : String)
case class Ready(sender : Actor)
case class Result(result : String)
case object Stop
def consumer(n : Int) = actor {
loop {
react {
case Ready(sender) =>
sender ! Ready(self)
case Request(sender, payload) =>
println("request to consumer " + n + " with " + payload)
// some silly computation so the process takes awhile
val result = ((payload + payload + payload) map {case '0' => 'X'; case '1' => "-"; case c => c}).mkString
sender ! Result(result)
println("consumer " + n + " is done processing " + result)
case Stop => exit
}
}
}
// a pool of 10 consumers
val consumers = for (n <- 0 to 10) yield consumer(n)
val coordinator = actor {
loop {
react {
case msg @ Request(sender, payload) =>
consumers foreach {_ ! Ready(self)}
react {
// send the request to the first available consumer
case Ready(consumer) => consumer ! msg
}
case Stop =>
consumers foreach {_ ! Stop}
exit
}
}
}
// a little test loop - note that it's not doing anything with the results or telling the coordinator to stop
for (i <- 0 to 1000) coordinator ! Request(self, i.toString)
이 코드는 사용 가능한 소비자를 확인하고 해당 소비자에게 요청을 보냅니다. 대안은 무작위로 소비자에게 할당하거나 라운드 로빈 스케줄러를 사용하는 것입니다.
당신이하는 일에 따라 Scala 's Futures를 사용하는 것이 더 나을 것입니다. 예를 들어, 배우가 실제로 필요하지 않다면 위의 모든 기계는 다음과 같이 쓸 수 있습니다.
import scala.actors.Futures._
def transform(payload : String) = {
val result = ((payload + payload + payload) map {case '0' => 'X'; case '1' => "-"; case c => c}).mkString
println("transformed " + payload + " to " + result)
result
}
val results = for (i <- 0 to 1000) yield future(transform(i.toString))
이 질문이 어떻게 하향식을 정당화하는지 보지 못합니다. 스칼라에서 프로그래밍의 배우에 대한 전체 장을 읽고 대답을 확신 할 수 없다면 이는 완전히 유효한 질문입니다. –
액터를 사용하여 공유 리소스에 대한 액세스를 중재 할 수 있고 공유 리소스에 대한 다른 동기화는 필요하지 않기 때문에 단일 액터가 메시지를 순차적으로 처리합니다.메시지를 순차적으로 처리 할 수있는 경우 동기화 오류가 발생하지 않도록 배우 내부에서 잠금을 사용해야합니다. –