Jak mogę przekroczyć obietnicę w Raku?

9

Wiem, że mogę zaplanować, Promiseaby utrzymać się w określonym czasie

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

ale jak mogę zaplanować jego uszkodzenie? Mówiąc konkretnie, myślę o obietnicy, która „przekroczy limit czasu”, dzięki czemu pozostanie do pewnego czasu do dotrzymania, inaczej zawiedzie.

Mogę to zrobić z innym Promise, tak:

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

Ale wydaje się to trochę ... marnotrawstwem. Czy jest na to lepszy sposób?

jja
źródło

Odpowiedzi:

10

Częstym wzorem jest napisanie czegoś takiego:

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

Nie objawia się to jako zepsute Promise, choć nie jest to wcale złe (ponieważ w wielu przypadkach i tak trzeba rozróżnić anulowanie i błąd, więc nadal trzeba będzie dopasować typ wyjątku). Faktoring ma również tę zaletę, że $the-promisenie musi to być fakt, że masz dostęp do zatrzymania / przerwania.

Można to również zawrzeć w czymś takim:

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

Który ponownie będzie działał z dowolnym $promise, przekaże wynik lub wyjątek i w przeciwnym razie wyrzuci limit czasu.

Należy pamiętać o tym, że w rzeczywistości nie powodują one anulowania trwającej pracy. To może nie mieć znaczenia lub może być ważne. Jeśli to drugie, prawdopodobnie będziesz chciał:

  • A Promise, którego używasz do przekazania odwołania, które miało miejsce; zachowujesz go podczas anulowania i odpytujesz go w kodzie, który dokona anulowania
  • Aby spojrzeć na użycie Supplyparadygmatu zamiast tego, gdzie jest model anulowania (zamknięcie kranu).
Jonathan Worthington
źródło
3
Dzięki. To jest przydatne. A przynajmniej prowadzi do domu, że obietnice są tanie (!), A używanie ich tak, jak sugerujesz, lub tak, jak pierwotnie myślałem, jest w porządku. Nadal wydaje się, że powinien istnieć (bardziej?) Prosty sposób powiedzenia „jeśli obietnica nie została dotrzymana w ciągu X sekund, to uważaj ją za złamaną”. Rozumiem, że nie ma to sensu we wszystkich przypadkach, ale myślę, że w niektórych przypadkach ma to sens.
jja
3
Prawdopodobnie nadejdzie w przyszłości, jednak prawdopodobnie tylko wtedy, gdy będziemy mieli też pewne podstawowe zasady Promiseanulowania, ponieważ jego semantyka będzie nieco z nimi związana.
Jonathan Worthington