Como posso cumprir uma promessa em Raku?

9

Eu sei que posso agendar um Promisepara ser mantido em um determinado período de tempo com

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

mas como posso agendá-lo para ser quebrado? Especificamente, estou pensando em uma promessa que "atingirá o tempo limite", para que ela tenha uma certa quantidade de tempo a ser mantida ou então falhará.

Eu posso fazer isso com outro Promise, assim:

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

Mas isso parece um pouco ... desperdício. Existe uma maneira melhor de fazer isso?

jja
fonte

Respostas:

10

Um padrão comum é escrever algo como isto:

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

Isso não se manifesta como quebrado Promise, embora não seja de todo ruim (já que, em muitos casos, você precisa distinguir cancelamento x erro), então você ainda precisa fazer alguma correspondência no tipo de exceção). Esse fatoramento também tem a vantagem de que $the-promisenão é necessário que você tenha acesso para manter / interromper.

Pode-se também resumir isso em algo assim:

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

O que funcionará novamente com qualquer um $promise, transmitirá o resultado ou a exceção e lançará uma exceção de tempo limite.

O ponto a ter em mente com tudo isso é que eles não efetivamente cancelam o trabalho em andamento. Isso pode não importar, ou pode ser importante. Neste último caso, você provavelmente desejará:

  • Um Promiseque você usa para transmitir o cancelamento; você a mantém durante o cancelamento e a pesquisa no código que fará o cancelamento
  • Em Supplyvez disso, observe o uso do paradigma, onde existe um modelo de cancelamento (fechando a torneira).
Jonathan Worthington
fonte
3
Obrigado. Isso é útil. E, no mínimo, leva para casa que as promessas são baratas (!) E usá-las como você sugere, ou como eu pensava originalmente, está OK. Ainda parece que deveria haver uma maneira (mais?) Direta de dizer "se essa promessa não foi cumprida em X segundos, considere-a quebrada". Entendo que não fará sentido em todos os casos, mas acho que definitivamente faz sentido em alguns.
jja 6/02
3
Provavelmente virá no futuro, no entanto provavelmente apenas quando tivermos algum tipo de Promisecláusula de cancelamento no núcleo também, uma vez que sua semântica estará um pouco ligada a elas.
Jonathan Worthington