my $filenames;
my $given_job;
my $summary;
+my $state_regex;
my $why;
sub usage() {
--move-to=<queue> Move jobs to a different queue
Options:
--a, --attn Show jobs needing attention (e.g., failures)
+-a, --attn Show only jobs needing attention (e.g., failures)
-f, --filenames Show filenames of jobs and log files
-j, --job=<id> Act on the specified job (default: on all)
-q, --queue=<name> Act on the given queue
-s, --summary Show only a summary
+-S, --state=<regex> Act only on jobs whose state matches the given regex
-w, --why[=<lines>] In case of failed jobs, display last few lines of output
AMEN
exit 0;
"j|job=s" => \$given_job,
"q|queue=s" => \$queue_name,
"s|summary!" => \$summary,
+ "S|state=s" => \$state_regex,
"w|why:i" => \$why,
"help" => \&usage,
) or die "Try `bex queue --help' for more information.\n";
my @machines = BEX::Config::parse_machine_list(@ARGV ? @ARGV : '*');
my $queue = BEX::Queue->new($queue_name);
+# Status cache
+my %status_cache = ();
+sub get_status($$) {
+ my ($m, $j) = @_;
+ $status_cache{$m}{$j} or $status_cache{$m}{$j} = $queue->read_job_status($m, $j);
+ return $status_cache{$m}{$j};
+}
+sub get_stat($$) {
+ my ($m, $j) = @_;
+ return get_status($m, $j)->{'Status'} // 'UNKNOWN';
+}
+
# Select jobs
my %jobs = ();
my %machs = ();
if (defined $given_job) {
next if $j ne $given_job;
}
+ if (defined $attention) {
+ next if get_stat($m, $j) =~ m{^(NEW|NOPING)$};
+ }
+ if (defined $state_regex) {
+ next unless get_stat($m, $j) =~ m{^($state_regex)$};
+ }
push @{$jobs{$j}}, $m;
push @{$machs{$m}}, $j;
}
for my $m (keys %machs) {
$mach_locked{$m} = $queue->is_locked($m, undef);
for my $j (@{$machs{$m}}) {
- my $st = $queue->read_job_status($m, $j);
- my $s = $st->{"Status"} // "UNKNOWN";
- if ($attention) { next if $s =~ m{^(NEW|NOPING)$}; }
+ my $st = get_status($m, $j);
+ my $s = get_stat($m, $j);
$cnt_by_job{$j}{$s}++;
$cnt_by_mach{$m}{$s}++;
$why{$m}{$j} = "";