2009-06-05 4 views
1

Ich habe folgende Stück Code:Blockiert dieser Scala-Actor beim Erstellen eines neuen Actors in einem Handler?

actor { 
    loop { 
    react { 
     case SomeEvent => 
     //I want to submit a piece of work to a queue and then send a response 
     //when that is finished. However, I don't want *this* actor to block 
     val params = "Some args" 
     val f: Future[Any] = myQueue.submitWork(params); 
     actor { 
      //await here 
      val response = f.get 
      publisher ! response 
     } 

    } 
    } 
} 

Wie ich es verstanden, die äußere Darsteller nicht auf f.get blockieren, weil die tatsächlich von einem separaten Schauspieler durchgeführt wird (der einen im Inneren des SomeEvent Handler erstellt).

Ist das korrekt?

Antwort

2

Ja, das ist richtig. Dein äußerer Schauspieler wird einfach einen Schauspieler erschaffen und aussetzen (auf seine nächste Nachricht warten). Sei jedoch sehr vorsichtig mit dieser Art von Dingen. Der innere Akteur wird automatisch auf dem Scheduler gestartet, um von einem Thread behandelt zu werden. Dieser Thread wird auf diesem Future blockieren (das sieht für mich wie eine java.util.concurrent.Future aus). Wenn Sie dies oft genug tun, können Sie auf Probleme stoßen, bei denen alle verfügbaren Threads auf Futures blockieren. Ein Akteur ist im Grunde eine Arbeitswarteschlange, daher sollten Sie stattdessen diese Semantik verwenden.

Hier ist eine Version Ihres Codes, mit der Scalaz actors library. Diese Bibliothek ist viel einfacher und leichter zu verstehen als die Standard-Scala-Akteure (die Quelle ist buchstäblich eineinhalb Seiten). Es führt auch zu vielem Prüfcode:

actor {(e: SomeEvent) => promise { ... } to publisher } 

Diese Version ist vollständig nicht blockierend.

+0

Aber wenn ich Arbeit an eine Warteschlange sende und eine (juc) Zukunft zurückbekomme, wie vermeide ich das Blockieren in dem Fall, in dem ich die Warteschlangen-API nicht kontrolliere (dh wenn ich die Arbeitswarteschlange, so dass der Verlag Ereignisse nach Abschluss der Arbeit erhält)? –

+0

Können Sie der Arbeitswarteschlange beliebigen Code senden? Wenn dies der Fall ist, können Sie eine Berechnung mit Einheitenwerten einreichen, die mit dem Senden einer Nachricht an einen Ihrer Akteure endet. Und ignorieren Sie einfach die Zukunft [Einheit] – Apocalisp

+0

Ich habe die Frage bearbeitet, um es ein bisschen klarer zu machen, was genau ich rufe, wenn ich submitWork. Grundsätzlich nein, ich kann keine willkürlichen Runnables/Callables einreichen. Allerdings habe ich ursprünglich den gesamten Code geschrieben, also sieht es so aus, als müsste ich nur eine API-Änderung vornehmen :-) –

Verwandte Themen