2 # Batch EXecutor 2.0 -- Parallel Execution Using Screen
3 # (c) 2011 Martin Mares <mj@ucw.cz>
17 "q|queue=s" => \$queue_name,
18 "text!" => \$text_mode,
20 Usage: bprun [<options>] [[!]<machine-or-class> ...]
23 -q, --queue=<name> Run jobs in the given queue
24 --text Use textual user interface instead of curses
27 $ENV{'STY'} or die "Please run me under Screen\n";
28 my @machines = BEX::Config::parse_machine_list(@ARGV ? @ARGV : '*');
29 my $queue = BEX::Queue->new($queue_name);
31 my $fifo_name = $queue->{'Name'} . '/status-fifo';
33 mkfifo $fifo_name, 0700 or die "Cannot create $fifo_name: $!";
34 open FIFO, '+<', $fifo_name or die "Cannot open $fifo_name: $!";
36 my $ui = ($text_mode ? BEX::bprun::text->new : BEX::bprun::curses->new);
39 my $max = $BEX::Config::max_parallel_jobs;
41 while (keys %running || @machines) {
42 if (@machines && keys %running < $max) {
43 my $mach = shift @machines;
44 my @jobs = $queue->scan($mach);
46 $ui->update($mach, undef, 'START');
47 system 'screen', '-t', $mach, './brun', "--status-fifo=$fifo_name", $mach;
48 !$? or $ui->update($mach, undef, 'INTERR');
49 $running{$mach} = 'START';
54 my ($mach, $jid, $stat) = /^! (\S+) (\S+) (\S+)$/;
56 $ui->err("Received invalid status message <$_>");
59 if (!defined $running{$mach}) {
60 $ui->err("Received status message <$_> for a machine which does not run");
63 $running{$mach} = $stat;
64 $ui->update($mach, ($jid eq '-' ? undef : $jid), $stat);
65 if ($stat eq 'DONE') {
66 delete $running{$mach};
74 package BEX::bprun::text;
84 my ($ui, $mach, $jid, $stat) = @_;
85 print +($mach // '-'), (defined($jid) ? ":$jid" : ""), " $stat\n";
90 print STDERR "ERROR: $msg\n";
93 package BEX::bprun::curses;
106 has_colors && COLORS >= 8 && COLOR_PAIRS >= 8 or die "Your terminal is too dumb for me\n";
112 $nrows = $C->getmaxy - 2;
113 if ($BEX::Config::max_parallel_jobs > $nrows) {
114 $BEX::Config::max_parallel_jobs = $nrows;
126 if (defined $by_host{$mach}) {
127 return $by_host{$mach};
133 while (defined $by_row[$i]) { $i++; }
136 $by_host{$mach} = $s;
142 delete $by_host{$s->{'Host'}};
143 $by_row[$s->{'Row'}] = undef;
148 my $mach = $s->{'Host'};
149 my $stat = $s->{'Status'} // "?";
150 my $jid = $s->{'Job'} // "";
151 my $text = sprintf("%-20s %-10s %s", $mach, $stat, $jid);
152 $C->addnstr($s->{'Row'}, 0, $text, $C->getmaxx);
158 my ($ui, $mach, $jid, $stat) = @_;
159 my $s = get_slot($mach);
161 $s->{'Status'} = $stat;
163 if ($stat eq 'DONE') { delete_slot($s); }