Wie kann ich ein Versprechen in Raku auslaufen lassen?

9

Ich weiß, dass ich einen Termin festlegen kann Promise, der in einer bestimmten Zeitspanne eingehalten werden soll

my $promise = Promise.in($seconds);

aber wie kann ich planen, dass es kaputt geht? Insbesondere denke ich an ein Versprechen, das "Timeout" sein wird, so dass es bis zu einer bestimmten Zeitspanne einzuhalten ist, sonst wird es scheitern.

Ich kann das mit einem anderen machen Promise, so:

my $promise = Promise.new;
...
Promise.in($seconds).then: { $promise.break };

Aber das fühlt sich ein bisschen ... verschwenderisch an. Gibt es einen besseren Weg, dies zu tun?

jja
quelle

Antworten:

10

Ein übliches Muster ist, so etwas zu schreiben:

await Promise.anyof($the-promise, Promise.in(10));
if $the-promise {
    # it finished ahead of the timeout
}
else {
    # it timed out
}

Das manifestiert sich nicht als defekt Promise, obwohl das nicht alles schlecht ist (da Sie in vielen Fällen ohnehin zwischen Stornierung und Fehler unterscheiden müssen, müssen Sie also immer noch einen Abgleich für den Ausnahmetyp durchführen). Dieses Factoring hat auch den Vorteil, dass $the-promisees nicht eines sein muss, auf das Sie Zugriff haben, um es zu behalten / zu unterbrechen.

Man könnte dies auch in so etwas einwickeln:

class TimedOut is Exception {}
sub timeout($promise, $time) {
    start {
        await Promise.anyof($promise, Promise.in($time));
        $promise ?? await($promise) !! die(TimedOut.new)
    }
}

Was wieder mit any funktioniert $promise, das Ergebnis oder die Ausnahme weitergibt und andernfalls eine Timeout-Ausnahme auslöst.

Bei alledem ist zu beachten, dass sie tatsächlich keine Stornierung der laufenden Arbeiten bewirken. Das ist vielleicht nicht wichtig oder wichtig. Wenn letzteres der Fall ist, möchten Sie wahrscheinlich Folgendes:

  • A Promise, mit dem Sie die Stornierung übermitteln, die stattgefunden hat; Sie behalten es beim Abbrechen und fragen es in dem Code ab, der die Stornierung vornimmt
  • Um stattdessen das SupplyParadigma zu verwenden, bei dem es ein Stornierungsmodell gibt (Schließen des Hahns).
Jonathan Worthington
quelle
3
Vielen Dank. Das ist nützlich. Und zumindest fährt es nach Hause, dass Versprechen billig (!) Sind und es in Ordnung ist, sie entweder so zu verwenden, wie Sie es vorschlagen oder wie ich es mir ursprünglich vorgestellt hatte. Es fühlt sich immer noch so an, als ob es eine (mehr?) Unkomplizierte Art geben sollte, zu sagen: "Wenn dieses Versprechen nicht in X Sekunden eingehalten wurde, dann halte es für gebrochen." Ich verstehe, dass es nicht in allen Fällen Sinn macht, aber ich denke, dass es in einigen Fällen definitiv Sinn macht.
Jja
3
Es wird wahrscheinlich in der Zukunft kommen, aber wahrscheinlich nur, wenn wir Promiseim Kern auch eine Art von Stornierungsbestimmungen haben, da seine Semantik etwas mit diesen verknüpft sein wird.
Jonathan Worthington