Execute an external program with timeout in Perl6
Proc::Async allows us to execute an external program asynchronously.
my $proc = Proc::Async.new("curl", "-s", "-o", "index.html", "http://www.cpan.org"); my $res = await $proc.start;
Can we use Proc::Async with a timeout? Proc::Async does not support it officially, but we can implement it easily. Take a look at this:
class Proc::Async::Timeout is Proc::Async { has $.timeout is rw; method start($self: |) { return callsame unless $.timeout; my $killer = Promise.in($.timeout).then: { $self.kill }; my $promise = callsame; Promise.anyof($promise, $killer).then: { $promise.result }; } } my $proc = Proc::Async::Timeout.new("perl", "-E", "sleep 5; warn 'end'"); $proc.timeout = 1; my $res = await $proc.start; say "maybe timeout" if $res.signal;
Wow! You could even do:
my $start = Proc::Async.^methods.first(*.name eq "start"); $start.wrap: method ($self: :$timeout, |c) { return callwith($self, |c) unless $timeout; my $killer = Promise.in($timeout).then: { $self.kill }; my $promise = callwith($self, |c); Promise.anyof($promise, $killer).then: { $promise.result }; }; say await Proc::Async.new("perl", "-E", 'sleep 3; say "end"').start(timeout => 2);
Wow Wow! If you find cooler ways, please let us know!