Les acteurs du processus, un message à la fois. Le schéma classique pour traiter plusieurs messages est d'avoir un coordonnateur de l'acteur avant pour un bassin de consommation des acteurs. Si vous utilisez réagir alors le consommateur de la piscine peut être grande, mais seulement utiliser un petit nombre de JVM threads. Voici un exemple où j'ai créer un pool de 10 consommateurs et un coordinateur de l'avant pour eux.
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)
Ce code tests pour voir qui à la consommation est disponible et envoie une demande pour le consommateur. Les Alternatives sont juste d'attribuer au hasard, à la consommation ou à l'utilisation d'un tournoi à la ronde du planificateur.
En fonction de ce que vous faites, vous pourriez être mieux servis avec de la Scala à Terme. Par exemple, si vous n'avez pas vraiment besoin des acteurs de toutes les machines ci-dessus peut être écrite comme
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))