Verwenden von Scala-Fortsetzungen mit netty / NIO-Listenern

9

Ich benutze die Netty-Bibliothek (Version 4 von GitHub). Es funktioniert großartig in Scala, aber ich hoffe, dass meine Bibliothek in der Lage ist, Fortsetzungsübergabestil für das asynchrone Warten zu verwenden.

Traditionell mit Netty würden Sie so etwas tun (ein Beispiel einer asynchronen Verbindungsoperation):

%Vor%

Wenn Sie eine Bibliothek implementieren (was ich bin), haben Sie im Grunde genommen drei einfache Möglichkeiten, um dem Benutzer der Bibliothek zu erlauben, nach der Verbindung etwas zu tun:

  1. Gib einfach ChannelFuture von deiner connect-Methode zurück und lass den Benutzer damit umgehen - das bietet nicht viel Abstraktion von netty.
  2. Nehmen Sie einen ChannelFutureListener als Parameter Ihrer Verbindungsmethode und fügen Sie ihn als Listener zur ChannelFuture hinzu.
  3. Nimm ein Callback-Funktionsobjekt als Parameter deiner connect-Methode und rufe es innerhalb des von dir erstellten ChannelFutureListeners auf (dies würde für einen Callback-getriebenen Stil ähnlich wie node.js sorgen)

Was ich versuche, ist eine vierte Option; Ich habe es oben nicht erwähnt, weil es nicht einfach ist.

Ich möchte scala-begrenzte Fortsetzungen verwenden, um die Verwendung der Bibliothek etwas wie eine blockierende Bibliothek zu machen, aber sie wird hinter den Kulissen nicht blockierend sein:

%Vor%

Stellen Sie sich vor, dass andere Lese- / Schreiboperationen auf dieselbe Weise implementiert werden. Das Ziel ist, dass der Code des Benutzers so aussehen kann:

%Vor%

Mit anderen Worten, das Programm wird wie ein einfaches blockierendes Programm aussehen, aber hinter den Kulissen gibt es kein Blocking oder Threading.

Das Problem, auf das ich gestoßen bin, ist, dass ich nicht ganz verstehe, wie die Typisierung begrenzter Fortsetzungen funktioniert. Wenn ich versuche, es auf die obige Weise zu implementieren, beschwert sich der Compiler, dass meine operationComplete -Implementierung tatsächlich Unit @scala.util.continuations.cpsParam[Unit,Unit => Unit] anstelle von Unit zurückgibt. Ich verstehe, dass es in scala's CPS eine Art "gotcha" gibt, in der Sie einen shift -Methoden-Rückgabetyp mit @suspendable kommentieren müssen, der den Aufruf-Stack bis zum reset weitergibt, aber es scheint nicht um eine Möglichkeit zu bieten, dies mit einer bereits existierenden Java-Bibliothek zu vereinbaren, die kein Konzept von begrenzten Fortsetzungen hat.

Ich habe das Gefühl, dass es einen Weg geben muss - wenn Swarm Fortsetzungen serialisieren und sie über das Netzwerk blockieren kann, um anderswo berechnet zu werden, dann muss es einfach möglich sein, eine Fortsetzung von einer bereits existierenden Java-Klasse aufzurufen. Aber ich kann nicht herausfinden, wie es gemacht werden kann. Müsste ich ganze Teile von netty in Scala umschreiben, um dies zu ermöglichen?

    
Jeremy 07.02.2012, 23:18
quelle

1 Antwort

4

Ich fand diese Erklärung von Scalas Fortsetzungen extrem hilfreich, als ich anfing. Achten Sie besonders auf die Teile, in denen er shift[A, B, C] und reset[B, C] erklärt. Das Hinzufügen eines Dummy null als letzte Anweisung von operationComplete sollte helfen.

Übrigens müssen Sie retrn() in einem anderen reset aufrufen, wenn darin möglicherweise shift verschachtelt ist.

Bearbeiten: Hier ist ein Arbeitsbeispiel

%Vor%

mit einer möglichen Ausgabe:

%Vor%     
shams 08.02.2012, 06:40
quelle

Tags und Links