Fixed bug #50081: --keep-order --round-robin should give predictable results.

This commit is contained in:
Ole Tange 2017-02-05 00:27:10 +01:00
parent 09cc44e209
commit 1229288418
5 changed files with 56 additions and 9 deletions

View file

@ -597,6 +597,19 @@ sub nindex {
push @robin_queue, (sort { $a->seq() <=> $b->seq() }
values %Global::running);
}
if($opt::keeporder) {
for my $job (@robin_queue) {
if($job->block_length() > 0) {
$written += $job->non_blocking_write();
} else {
$job->set_block($header_ref,$buffer_ref,$endpos,$recstart,$recend);
$block_passed = 1;
$job->set_virgin(0);
$written += $job->non_blocking_write();
last;
}
}
} else {
do {
$written = 0;
for my $job (@robin_queue) {
@ -615,6 +628,7 @@ sub nindex {
$sleep = $sleep/1.5+0.001;
}
} while($written and not $block_passed);
}
$sleep = ::reap_usleep($sleep);
}
return $written;
@ -961,6 +975,7 @@ sub options_hash {
"cat" => \$opt::cat,
"fifo" => \$opt::fifo,
"pipepart|pipe-part" => \$opt::pipepart,
"tee" => \$opt::tee,
"hgrp|hostgrp|hostgroup|hostgroups" => \$opt::hostgroups,
);
}
@ -7876,7 +7891,8 @@ sub start {
if($opt::pipe) {
my ($stdin_fh) = ::gensym();
$pid = open3_setpgrp($stdin_fh,$stdout_fh,$stderr_fh,$command);
if($opt::roundrobin) {
if($opt::roundrobin and not $opt::keeporder) {
# --keep-order will make sure the order will be reproducible
::set_fh_non_blocking($stdin_fh);
}
$job->set_fh(0,"w",$stdin_fh);

View file

@ -988,6 +988,9 @@ to see the difference:
If used with B<--onall> or B<--nonall> the output will grouped by
sshlogin in sorted order.
If used with B<--pipe --roundrobin> and the same input, the jobslots
will get the same blocks in the same order in every run.
=item B<-L> I<max-lines>

View file

@ -196,6 +196,7 @@ par_result_replace() {
rm -rf /tmp/par_*_49983-*
}
export -f $(compgen -A function | grep par_)
compgen -A function | grep par_ | sort |
parallel -j6 --tag -k --joblog +/tmp/jl-`basename $0` '{} 2>&1'

View file

@ -79,6 +79,31 @@ par_pipepart_block() {
rm /run/shm/parallel$$
}
par_keeporder_roundrobin() {
echo 'bug #50081: --keep-order --round-robin should give predictable results'
export PARALLEL="-j13 --block 1m --pipe --roundrobin"
random500m() {
< /dev/zero openssl enc -aes-128-ctr -K 1234 -iv 1234 2>/dev/null |
head -c 500m;
}
a=$(random500m | parallel -k 'echo {#} $(md5sum)' | sort)
b=$(random500m | parallel -k 'echo {#} $(md5sum)' | sort)
c=$(random500m | parallel 'echo {#} $(md5sum)' | sort)
if [ "$a" == "$b" ] ; then
# Good: -k should be == -k
if [ "$a" == "$c" ] ; then
# Bad: without -k the command should give different output
echo 'Broken: a == c'
printf "$a\n$b\n$c\n"
else
echo OK
fi
else
echo 'Broken: a <> b'
printf "$a\n$b\n$c\n"
fi
}
export -f $(compgen -A function | grep par_)
compgen -A function | grep par_ | sort | parallel -j6 --tag -k '{} 2>&1'

View file

@ -4,6 +4,8 @@ par_children_receive_sig Got TERM
par_children_receive_sig Got TERM
par_children_receive_sig Got INT
par_children_receive_sig Got TERM
par_keeporder_roundrobin bug #50081: --keep-order --round-robin should give predictable results
par_keeporder_roundrobin OK
par_kill_int_twice ### Are children killed if GNU Parallel receives INT twice? There should be no sleep at the end
par_kill_int_twice bash-+-perl---bash---sleep
par_kill_int_twice `-pstree