Comment puis-je expirer une promesse à Raku?

9

Je sais que je peux planifier une Promiseconservation dans un laps de temps donné avec

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

mais comment puis-je planifier sa rupture? Plus précisément, je pense à une promesse qui "expirera", de sorte qu'elle ait jusqu'à un certain temps pour être conservée, sinon elle échouera.

Je peux le faire avec un autre Promise, comme ceci:

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

Mais cela semble un peu ... inutile. Y a-t-il une meilleure manière de faire cela?

jja
la source

Réponses:

10

Un modèle courant consiste à écrire quelque chose comme ceci:

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

Cela ne se manifeste pas comme un problème Promise, bien que ce ne soit pas tout à fait mauvais (car vous devez de toute façon distinguer l'annulation de l'erreur dans de nombreux cas, vous devrez donc toujours faire une correspondance sur le type d'exception). Cet affacturage présente également l'avantage de $the-promisene pas avoir à être celui auquel vous avez accès pour conserver / casser.

On pourrait également conclure cela dans quelque chose comme ceci:

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

Ce qui fonctionnera à nouveau avec any $promise, transmettra le résultat ou l'exception et lèvera une exception expirée autrement.

La chose à garder à l'esprit avec tous ces éléments est qu'ils n'effectuent en fait aucune annulation des travaux en cours. Cela n'a peut-être pas d'importance, ou cela peut être important. Si ce dernier, vous voudrez probablement soit:

  • A Promiseque vous utilisez pour transmettre l'annulation ayant eu lieu; vous le conservez lors de l'annulation, et l'interrogez dans le code qui fera l'annulation
  • Envisager d'utiliser le Supplyparadigme à la place, où il existe un modèle d'annulation (fermeture du robinet).
Jonathan Worthington
la source
3
Merci. C'est utile. Et à tout le moins, cela ramène à la maison que les promesses sont bon marché (!) Et les utiliser soit comme vous le suggérez, ou comme je l'avais pensé à l'origine, est OK. Il semble toujours qu'il devrait y avoir une (plus?) Manière simple de dire "si cette promesse n'a pas été tenue en X secondes, alors considérez-la comme rompue". Je comprends que cela n'a pas de sens dans tous les cas, mais je pense que cela a du sens dans certains.
JJA
3
Cela viendra probablement à l'avenir, mais probablement seulement lorsque nous aurons également une sorte de Promisedispositions d'annulation, car sa sémantique sera quelque peu liée à celles-ci.
Jonathan Worthington