I have a perl6 program that runs a external program via Proc::Async
and tries to read its stdout
. It's possible that the portion of the code that is supposed to read the stdout somehow fails to do so, but other parts of the program will actually kill the external process in order to clean things up. However, after killing such process, and then await the promise, it blocks forever..., how can I avoid perl6 from blocking on awaiting a killed Proc::Async
whose stdout
is piped but not consumed? I think the following snippet illustrate the problem:
#!/usr/bin/env perl6
#
my $proc = Proc::Async.new(<cat /dev/urandom>);
my $supply = $proc.stdout(:bin);
my $promise = $proc.start;
$proc.ready.then: {
shell <<ps auxf | grep [u]random>>;
put "Terminating process {$_.result} …";
$proc.kill(SIGTERM);
}
sleep 1;
if shell(<<ps auxf | grep [u]random>>).exitcode ≠ 0 {
put "processed killed!";
}
put "awaiting $proc ({$proc.command}) …";
await $promise; # <--- blocked here :(
The Promise
returned from start
is only kept once any obtained Supply
of the output streams has delivered all of its events. This means one can assume that all output has been delivered by the time the Promise
is kept, which overall greatly simplifies working with Proc::Async
(without this behavior, we'd likely see a good number of buggy programs that lose output). However, if that Supply
is never tapped, then there's no way for that to happen, thus the hang.
The solution is to .tap
the stdout
Supply
without providing any callback:
$proc.stdout(:bin).tap;
Which will simply discard the output.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With