-
-
Save zoffixznet/c737b799dec4856ef7ffee75d9b5339f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use v6.d.PREVIEW; | |
module Proc::Q { | |
sub proc-q ( | |
+@commands where .so && .all ~~ List & .so, | |
:@tags where .elems == @commands && .all ~~ Cool = @commands, | |
:@in where .elems == @commands|0 && .all ~~ Cool, | |
Numeric :$timeout where .DEFINITE.not | $_ > 0, | |
UInt:D :$batch where .so = 8, | |
Bool:D :$out = True, | |
Bool:D :$err = True, | |
Bool:D :$merge where .not | .so & $out & $err = False, | |
--> Supply:D | |
) is export { | |
supply (@commands Z @tags Z @in).batch($batch).map: -> $pack { | |
my @results = $pack.map: -> ($command, $tag, $in) { | |
start do with Proc::Async.new: |$command, :w($in.so) -> $proc { | |
my $out-res = ''; my $err-res = ''; my $mer-res = ''; | |
$out and $proc.stdout.tap: $out-res ~= *; | |
$err and $proc.stderr.tap: $err-res ~= *; | |
if $merge { | |
$proc.stdout.tap: $mer-res ~= *; | |
$proc.stderr.tap: $mer-res ~= *; | |
} | |
my $prom = $proc.start; | |
if $in { | |
await $in ~~ Blob ?? $proc.write: $in !! $proc.print: $in; | |
$proc.close-stdin; | |
} | |
my $killed = False; | |
$timeout.DEFINITE and Promise.in($timeout).then: { | |
$prom or try { | |
$killed = True; | |
say "Killing!"; say $proc.kill: SIGTERM; | |
# Promise.in(½).then: $proc.kill: SIGTERM; | |
# Promise.in(1).then: $proc.kill: SIGSEGV; | |
} | |
} | |
my $proc-obj = await $prom; | |
class Res { | |
has Str:D $.err is required; | |
has Str:D $.out is required; | |
has Str:D $.merged is required; | |
has Int:D $.exitcode is required; | |
has Str:D $.tag is required; | |
has Bool:D $.killed is required; | |
}.new: :err($err-res), :out($out-res), :merged($mer-res), | |
:$tag, :$killed, :exitcode($proc-obj.exitcode); | |
} | |
} | |
while @results { | |
await Promise.anyof: @results; | |
my @ready = @results.grep: *.so; | |
@results .= grep: none @ready; | |
emit .status ~~ Kept ?? .result !! .cause for @ready; | |
} | |
} | |
} | |
import Proc::Q; | |
my @commands = <foo bar ber meow moo>; | |
my $sup = proc-q @commands.map({( | |
$*EXECUTABLE, '-e', | |
'signal(SIGSEGV).tap: {say "got a signal"};' | |
~ 'say "\qq[$_]" ~ $*IN.slurp; note "meows";' | |
~ ' sleep ' ~ ($++ > 2 ?? $++ !! 1000) | |
~ '; exit ' ~ $++ | |
)}), | |
:tags[@commands.map: 'tag-' ~ *], :in[@commands».uc], :timeout(3), :merge; | |
my @res; react whenever $sup { @res.push: $_ } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment