Frage

Die Antwort eine aktuelle Frage von mir angezeigt dass ein Schauspieler seine Nachrichten verarbeitet einen nach dem anderen . Ist das wahr? Ich sehe nichts, was ausdrücklich sagt, dass (in Programmierung in Scala ), die den folgenden Ausschnitt enthält (pp. 593)

  

Wenn [die react Methode] eine Nachricht findet, die behandelt werden können, [es] wird plant den Umgang mit dieser Meldung für die spätere Ausführung und eine Ausnahme auslösen

(Schwerpunkt meiner eigenen). Zwei verwandte (und sich gegenseitig ausschließende) Fragen:

  1. Schauspieler Unter der Annahme, simulatenously mehrere Nachrichten verarbeiten kann, wie kann ich einen Schauspieler zwingen Nachrichten: 1 zu einem Zeitpunkt, zu verarbeiten (wenn das ist, was ich tun wollen)? (Mit receive?)
  2. Schauspieler Unter der Annahme verarbeitet Nachrichten einen nach dem anderen, wie würde ich einen Schauspieler am besten implementieren, die in der Tat könnte Prozessmeldungen gleichzeitig

edit: ein wenig getestet tun scheint out zu tragen, dass ich falsch liege und dass die Akteure sind in der Tat sequentiell. Es ist also Frage # 2, die ich beantworten muß

War es hilfreich?

Lösung

Schauspieler verarbeiten eine Nachricht zu einer Zeit. Das klassische Muster mehr Nachrichten zu verarbeiten, ist einen Koordinator Schauspieler Front für einen Pool von Verbrauchern Akteure zu haben. Wenn Sie reagieren verwenden dann kann der Verbraucher Pool groß sein, sondern nur noch eine geringe Anzahl von JVM-Threads verwenden. Hier ist ein Beispiel, wo ich einen Pool von 10 Verbrauchern und einem Koordinator nach vorne für sie erstellen.

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)

Dieser Code prüft, um zu sehen, welche Verbraucher verfügbar ist und sendet eine Anfrage an diesen Verbraucher. Alternativen sind nur zufällig an den Verbraucher zuweisen oder einen Round-Robin-Scheduler zu verwenden.

Je nachdem, was Sie tun, werden Sie vielleicht besser mit Scala Futures serviert. Wenn Sie zum Beispiel nicht wirklich Akteure müssen dann alle der oben genannten Maschinen könnten als

geschrieben
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))

Andere Tipps

Ich denke, die Antwort ist, dass ein Actor keine Nachrichten aynchronously verarbeiten kann. Wenn Sie eine Actor haben, die Nachrichten hören sollte, wo diese Nachrichten können asynchron behandelt werden , dann könnte es wie folgt geschrieben werden:

val actor_ = actor {

  loop {
    react {
      case msg =>
        //create a new actor to execute the work. The framework can then 
        //manage the resources effectively
        actor {
          //do work here
        }
      }
    }
  }

Wenn Sie mehrere Dinge tun wollen, dann sollten Sie mit mehreren Akteuren werden. Der ganze Grund Akteure zu nutzen, um die Arbeit auf mehrere voneinander unabhängige Prozesse aufzuteilen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top