¿Cómo puedo expirar una promesa en Raku?

9

Sé que puedo programar una Promisepara que se mantenga en un período de tiempo determinado con

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

pero ¿cómo puedo programarlo para que se rompa? Específicamente, estoy pensando en una promesa que "caducará", de modo que tenga una cierta cantidad de tiempo para cumplir o de lo contrario fallará.

Puedo hacer esto con otro Promise, así:

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

Pero esto se siente un poco ... derrochador. ¿Hay una mejor manera de hacer esto?

jja
fuente

Respuestas:

10

Un patrón común es escribir algo como esto:

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

Eso no se manifiesta como roto Promise, aunque eso no es del todo malo (ya que de todos modos necesita distinguir la cancelación frente al error, por lo que aún tendría que hacer algunas coincidencias en el tipo de excepción). Esta factorización también tiene la ventaja de que $the-promiseno tiene que ser una a la que tenga acceso para mantener / romper.

También se podría resumir esto en algo como esto:

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

Que de nuevo funcionará con cualquiera $promise, pasará el resultado o la excepción, y lanzará una excepción de tiempo de espera de otra manera.

Lo que hay que tener en cuenta con todo esto es que en realidad no efectúan ninguna cancelación del trabajo en progreso. Eso puede no importar, o puede ser importante. Si es lo último, probablemente querrás:

  • A Promiseque utilizas para transmitir la cancelación que ha tenido lugar; lo guarda al cancelar y lo sondea en el código que hará la cancelación
  • Para ver el uso del Supplyparadigma en su lugar, donde hay un modelo de cancelación (cerrando el grifo).
Jonathan Worthington
fuente
3
Gracias. Esto es útil. Y por lo menos conduce a casa que las promesas son baratas (!) Y está bien usarlas como sugieres, o como había pensado originalmente. Todavía parece que debería haber una (¿más?) Forma directa de decir "si esta promesa no se ha cumplido en X segundos, entonces considérela rota". Entiendo que no tendrá sentido en todos los casos, pero creo que definitivamente tiene sentido en algunos.
jja
3
Probablemente vendrá en el futuro, sin embargo, probablemente solo cuando tengamos algún tipo de Promisedisposiciones de cancelación en el núcleo también, ya que su semántica estará un tanto ligada a esas.
Jonathan Worthington