]> mj.ucw.cz Git - bex.git/commitdiff
First cursey version of bprun
authorMartin Mares <mj@ucw.cz>
Mon, 31 Oct 2011 15:55:08 +0000 (16:55 +0100)
committerMartin Mares <mj@ucw.cz>
Mon, 31 Oct 2011 15:55:08 +0000 (16:55 +0100)
bprun

diff --git a/bprun b/bprun
index 0949c4ab28dde28e567767cf84b0d16561db32bb..b75a7fecee09264a2b9733fce13e43bc84918509 100755 (executable)
--- a/bprun
+++ b/bprun
@@ -11,14 +11,17 @@ use lib 'lib';
 use BEX;
 
 my $queue_name;
+my $text_mode;
 
 GetOptions(
        "q|queue=s" => \$queue_name,
+       "text!" => \$text_mode,
 ) or die <<AMEN ;
 Usage: bprun [<options>] [[!]<machine-or-class> ...]
 
 Options:
 -q, --queue=<name>     Run jobs in the given queue
+    --text             Use textual user interface instead of curses
 AMEN
 
 $ENV{'STY'} or die "Please run me under Screen\n";
@@ -30,16 +33,19 @@ unlink $fifo_name;
 mkfifo $fifo_name, 0700 or die "Cannot create $fifo_name: $!";
 open FIFO, '+<', $fifo_name or die "Cannot open $fifo_name: $!";
 
+my $ui = ($text_mode ? BEX::bprun::text->new : BEX::bprun::curses->new);
+
 my %running = ();
 my $max = $BEX::Config::max_parallel_jobs;
 
-while (%running || @machines) {
+while (keys %running || @machines) {
        if (@machines && keys %running < $max) {
                my $mach = shift @machines;
-               $queue->scan($mach) or next;
-               print "$mach: START\n";
+               my @jobs = $queue->scan($mach);
+               @jobs or next;
+               $ui->update($mach, undef, 'START');
                system 'screen', '-t', $mach, './brun', "--status-fifo=$fifo_name", $mach;
-               !$? or print "$mach: Failed to run!\n";
+               !$? or $ui->update($mach, undef, 'INTERR');
                $running{$mach} = 'START';
                next;
        }
@@ -47,15 +53,15 @@ while (%running || @machines) {
        chomp;
        my ($mach, $jid, $stat) = /^! (\S+) (\S+) (\S+)$/;
        if (!defined $stat) {
-               print "ERROR: Received invalid status message <$_>\n";
+               $ui->err("Received invalid status message <$_>");
                next;
        }
        if (!defined $running{$mach}) {
-               print "ERROR: Received status message <$_> for a machine which does not run\n";
+               $ui->err("Received status message <$_> for a machine which does not run");
                next;
        }
-       $running{$mach} = $stat . ($jid eq '-' ? "" : ":$jid");
-       print "$mach: ", $running{$mach}, "\n";
+       $running{$mach} = $stat;
+       $ui->update($mach, ($jid eq '-' ? undef : $jid), $stat);
        if ($stat eq 'DONE') {
                delete $running{$mach};
        }
@@ -63,3 +69,96 @@ while (%running || @machines) {
 
 close FIFO;
 unlink $fifo_name;
+$ui->done;
+
+package BEX::bprun::text;
+
+sub new($) {
+       return bless {};
+}
+
+sub done($) {
+}
+
+sub update($$$$) {
+       my ($ui, $mach, $jid, $stat) = @_;
+       print +($mach // '-'), (defined($jid) ? ":$jid" : ""), " $stat\n";
+}
+
+sub err($$) {
+       my ($ui, $msg) = @_;
+       print STDERR "ERROR: $msg\n";
+}
+
+package BEX::bprun::curses;
+
+use Curses;
+
+my $C;
+
+my $nrows;
+my @by_row = ();
+my %by_host = ();
+
+sub new($) {
+       $C = new Curses;
+       start_color;
+       has_colors && COLORS >= 8 && COLOR_PAIRS >= 8 or die "Your terminal is too dumb for me\n";
+       cbreak; noecho;
+       $C->intrflush(0);
+       $C->keypad(1);
+       $C->meta(1);
+       $C->clear;
+       $nrows = $C->getmaxy - 2;
+       if ($BEX::Config::max_parallel_jobs > $nrows) {
+               $BEX::Config::max_parallel_jobs = $nrows;
+       }
+       return bless {};
+}
+
+sub done($)
+{
+       endwin;
+}
+
+sub get_slot($) {
+       my ($mach) = @_;
+       if (defined $by_host{$mach}) {
+               return $by_host{$mach};
+       }
+       my $s = {
+               'Host' => $mach,
+       };
+       my $i = 0;
+       while (defined $by_row[$i]) { $i++; }
+       $s->{'Row'} = $i;
+       $by_row[$i] = $s;
+       $by_host{$mach} = $s;
+       return $s;
+}
+
+sub delete_slot($) {
+       my ($s) = @_;
+       delete $by_host{$s->{'Host'}};
+       $by_row[$s->{'Row'}] = undef;
+}
+
+sub redraw_slot($) {
+       my ($s) = @_;
+       my $mach = $s->{'Host'};
+       my $stat = $s->{'Status'} // "?";
+       my $jid = $s->{'Job'} // "";
+       my $text = sprintf("%-20s %-10s %s", $mach, $stat, $jid);
+       $C->addnstr($s->{'Row'}, 0, $text, $C->getmaxx);
+       $C->clrtoeol;
+       $C->refresh;
+}
+
+sub update($$$$) {
+       my ($ui, $mach, $jid, $stat) = @_;
+       my $s = get_slot($mach);
+       $s->{'Job'} = $jid;
+       $s->{'Status'} = $stat;
+       redraw_slot($s);
+       if ($stat eq 'DONE') { delete_slot($s); }
+}