Wie benutze ich Scala ARM mit Futures?

8

Ich möchte das ARM-Muster (Automated Resource Management) implementieren, bei dem die Ressource asynchron verwendet wird.

Das Problem

Angenommen, meine Ressource sieht folgendermaßen aus:

%Vor%

Das gewünschte Verwendungsmuster ist:

%Vor%

Die abgebildeten Funktionen können komplex sein und Verzweigungen und Verkettungen von Futures beinhalten, die wiederholt Aufrufe an Methoden von r auslösen, die Futures zurückgeben.

Ich möchte sicherstellen, dass r.close() aufgerufen wird, nachdem alle zukünftige Fortsetzungen abgeschlossen wurden (oder fehlgeschlagen sind). Dies manuell an jeder Call-Site zu tun ist fehleranfällig. Dies erfordert eine ARM-Lösung.

Lösungsversuche

Die Scala-Arm-Bibliothek ist normalerweise synchron. Dieser Code würde nicht das Richtige tun, denn close () würde aufgerufen werden, bevor die Futures innerhalb des Blocks abgeschlossen wurden:

%Vor%

Ich benutze diesen Wrapper jedoch:

%Vor%

Dann würde die Aufrufseite wie folgt aussehen:

%Vor%

Aber dann wäre der Code innerhalb des Blocks verantwortlich für die Rückgabe eines Futures, der abgeschlossen wurde, als alle anderen Futures, die von diesem Block erstellt wurden, abgeschlossen waren. Wenn es nicht versehentlich passiert ist, würde die Ressource wieder geschlossen werden, bevor alle Futures, die sie verwenden, abgeschlossen sind. Und es würde keine statische Überprüfung geben, um diesen Fehler zu erfassen. Zum Beispiel wäre dies ein Laufzeitfehler:

%Vor%

Wie löst man das?

Anscheinend könnte ich Scala-Arm's Confined Continuation Support (CPS) verwenden. Es sieht ein wenig komplex aus und ich habe Angst, es falsch zu machen. Und es erfordert die Aktivierung eines Compiler-Plugins. Außerdem ist mein Team sehr neu in scala und ich möchte nicht verlangen, dass sie CPS verwenden.

Ist CPS der einzige Weg vorwärts? Gibt es eine Bibliothek oder ein Entwurfsmuster, das dies einfacher mit Futures oder einem Beispiel dafür mit Scala-Arm macht?

    
danarmak 21.12.2013, 15:47
quelle

1 Antwort

2

Reaktive Erweiterungen (Rx) könnten eine alternative Lösung sein. Es gibt eine zunehmende Dynamik um dieses Programmierparadigma, das jetzt in vielen Sprachen einschließlich Scala verfügbar ist.

Die Basis von Rx besteht darin, ein Observable zu erstellen, das eine Quelle asynchroner Ereignisse ist. Observable kann auf raffinierte Weise angekettet werden, das ist seine Kraft. Sie abonnieren ein Observable, um auf die Ereignisse onNext, onError und onComplete zu warten. Sie erhalten auch ein Abonnement zurück, mit dem Sie abbrechen können.

Ich denke, Sie würden wahrscheinlich einen Aufruf von resource.close () in und onCompleted und / oder onError hinzufügen.

Siehe RxScala-Dokumente für:

%Vor%

Weitere Informationen:

  • RxScala-Seite: Ссылка
  • RxScala Beobachtbar: Ссылка
  • Gutes Intro von Ben Christensen bei NetFlix: Ссылка
  • Erik Meijer gibt Codebeispiele für verkettete Observable und im Kurs Coursera Prinzipien reaktiver Programmierung von Martin Odersky, Erik Meijer und Roland Kuhn.
reggoodwin 21.12.2013 18:45
quelle