File Coverage

blib/lib/Minion/Command/minion/job.pm
Criterion Covered Total %
statement 9 60 15.0
branch 0 38 0.0
condition 0 6 0.0
subroutine 3 17 17.6
pod 1 1 100.0
total 13 122 10.6


line stmt bran cond sub pod time code
1             package Minion::Command::minion::job;
2 1     1   24111 use Mojo::Base 'Mojolicious::Command';
  1         3  
  1         8  
3              
4 1     1   730 use Mojo::JSON qw(decode_json);
  1         16926  
  1         112  
5 1     1   15 use Mojo::Util qw(getopt tablify);
  1         1  
  1         1222  
6              
7             has description => 'Manage Minion jobs';
8             has usage => sub { shift->extract_usage };
9              
10             sub run {
11 0     0 1   my ($self, @args) = @_;
12              
13 0           my ($args, $options) = ([], {});
14             getopt \@args,
15             'A|attempts=i' => \$options->{attempts},
16 0     0     'a|args=s' => sub { $args = decode_json($_[1]) },
17             'b|broadcast=s' => (\my $command),
18             'd|delay=i' => \$options->{delay},
19             'E|expire=i' => \$options->{expire},
20             'e|enqueue=s' => \my $enqueue,
21             'f|foreground' => \my $foreground,
22             'H|history' => \my $history,
23             'L|locks' => \my $locks,
24             'l|limit=i' => \(my $limit = 100),
25 0     0     'n|notes=s' => sub { $options->{notes} = decode_json($_[1]) },
26             'o|offset=i' => \(my $offset = 0),
27 0     0     'P|parent=s' => sub { push @{$options->{parents}}, $_[1] },
  0            
28             'p|priority=i' => \$options->{priority},
29 0     0     'q|queue=s' => sub { push @{$options->{queues}}, $options->{queue} = $_[1] },
  0            
30             'R|retry' => \my $retry,
31             'retry-failed' => \my $retry_failed,
32             'remove' => \my $remove,
33             'remove-failed' => \my $remove_failed,
34 0     0     'S|state=s' => sub { push @{$options->{states}}, $_[1] },
  0            
35             's|stats' => \my $stats,
36             'T|tasks' => \my $tasks,
37 0     0     't|task=s' => sub { push @{$options->{tasks}}, $_[1] },
  0            
38             'U|unlock=s' => \my $unlock,
39             'w|workers' => \my $workers,
40 0           'x|lax=s' => \$options->{lax};
41              
42             # Worker remote control command
43 0           my $minion = $self->app->minion;
44 0 0         return $minion->backend->broadcast($command, $args, \@args) if $command;
45              
46             # Enqueue
47 0 0         return say $minion->enqueue($enqueue, $args, $options) if $enqueue;
48              
49             # Show stats
50 0 0         return $self->_stats if $stats;
51              
52             # Show history
53 0 0         return print Minion::_dump($minion->history) if $history;
54              
55             # List tasks
56 0 0         return print tablify [map { [$_, $minion->class_for_task($_)] } keys %{$minion->tasks}] if $tasks;
  0            
  0            
57              
58             # Iterate through failed jobs
59 0 0   0     return $minion->jobs({states => ['failed']})->each(sub { $minion->job($_->{id})->remove }) if $remove_failed;
  0            
60 0 0   0     return $minion->jobs({states => ['failed']})->each(sub { $minion->job($_->{id})->retry }) if $retry_failed;
  0            
61              
62             # Locks
63 0 0         return $minion->unlock($unlock) if $unlock;
64 0 0         return $self->_list_locks($offset, $limit, @args ? {names => \@args} : ()) if $locks;
    0          
65              
66             # Workers
67 0 0         my $id = @args ? shift @args : undef;
68 0 0         return $id ? $self->_worker($id) : $self->_list_workers($offset, $limit) if $workers;
    0          
69              
70             # List jobs
71 0 0         return $self->_list_jobs($offset, $limit, $options) unless defined $id;
72 0 0         die "Job does not exist.\n" unless my $job = $minion->job($id);
73              
74             # Remove job
75 0 0 0       return $job->remove || die "Job is active.\n" if $remove;
76              
77             # Retry job
78 0 0 0       return $job->retry($options) || die "Job is active.\n" if $retry;
79              
80             # Perform job in foreground
81 0 0 0       return $minion->foreground($id) || die "Job is not ready.\n" if $foreground;
82              
83             # Job info
84 0           print Minion::_dump(Minion::_datetime($job->info));
85             }
86              
87             sub _list_jobs {
88 0     0     my $jobs = shift->app->minion->backend->list_jobs(@_)->{jobs};
89 0           print tablify [map { [@$_{qw(id state queue task)}] } @$jobs];
  0            
90             }
91              
92             sub _list_locks {
93 0     0     my $locks = shift->app->minion->backend->list_locks(@_)->{locks};
94 0           @$locks = map { Minion::_datetime($_) } @$locks;
  0            
95 0           print tablify [map { [@$_{qw(name expires)}] } @$locks];
  0            
96             }
97              
98             sub _list_workers {
99 0     0     my $workers = shift->app->minion->backend->list_workers(@_)->{workers};
100 0           my @workers = map { [$_->{id}, $_->{host} . ':' . $_->{pid}] } @$workers;
  0            
101 0           print tablify \@workers;
102             }
103              
104 0     0     sub _stats { print Minion::_dump(shift->app->minion->stats) }
105              
106             sub _worker {
107 0     0     my $worker = shift->app->minion->backend->list_workers(0, 1, {ids => [shift]})->{workers}[0];
108 0 0         die "Worker does not exist.\n" unless $worker;
109 0           print Minion::_dump(Minion::_datetime($worker));
110             }
111              
112             1;
113              
114             =encoding utf8
115              
116             =head1 NAME
117              
118             Minion::Command::minion::job - Minion job command
119              
120             =head1 SYNOPSIS
121              
122             Usage: APPLICATION minion job [OPTIONS] [IDS]
123              
124             ./myapp.pl minion job
125             ./myapp.pl minion job 10023
126             ./myapp.pl minion job -w
127             ./myapp.pl minion job -w 23
128             ./myapp.pl minion job -s
129             ./myapp.pl minion job -f 10023
130             ./myapp.pl minion job -q important -t foo -t bar -S inactive
131             ./myapp.pl minion job -Q 'host:localhost' -S inactive
132             ./myapp.pl minion job -e foo -a '[23, "bar"]'
133             ./myapp.pl minion job -e foo -x 1 -P 10023 -P 10024 -p 5 -q important
134             ./myapp.pl minion job -e 'foo' -n '{"test":123}'
135             ./myapp.pl minion job -R -d 10 -E 300 10023
136             ./myapp.pl minion job --remove 10023
137             ./myapp.pl minion job --retry-failed
138             ./myapp.pl minion job -n '["test"]'
139             ./myapp.pl minion job -L
140             ./myapp.pl minion job -L some_lock some_other_lock
141             ./myapp.pl minion job -b jobs -a '[12]'
142             ./myapp.pl minion job -b jobs -a '[12]' 23 24 25
143              
144             Options:
145             -A, --attempts Number of times performing this new job will be
146             attempted, defaults to 1
147             -a, --args Arguments for new job or worker remote control
148             command in JSON format
149             -b, --broadcast Broadcast remote control command to one or more
150             workers
151             -d, --delay Delay new job for this many seconds
152             -E, --expire New job is valid for this many seconds before
153             it expires
154             -e, --enqueue New job to be enqueued
155             -f, --foreground Retry job in "minion_foreground" queue and
156             perform it right away in the foreground (very
157             useful for debugging)
158             -H, --history Show queue history
159             -h, --help Show this summary of available options
160             --home Path to home directory of your application,
161             defaults to the value of MOJO_HOME or
162             auto-detection
163             -L, --locks List active named locks
164             -l, --limit Number of jobs/workers to show when listing
165             them, defaults to 100
166             -m, --mode Operating mode for your application, defaults to
167             the value of MOJO_MODE/PLACK_ENV or
168             "development"
169             -n, --notes Notes in JSON format for new job or list only
170             jobs with one of these notes
171             -o, --offset Number of jobs/workers to skip when listing
172             them, defaults to 0
173             -P, --parent One or more jobs the new job depends on
174             -p, --priority Priority of new job, defaults to 0
175             -q, --queue Queue to put new job in, defaults to "default",
176             or list only jobs in these queues
177             -R, --retry Retry job
178             --retry-failed Retry all failed jobs at once
179             --remove Remove job
180             --remove-failed Remove all failed jobs at once
181             -S, --state List only jobs in these states
182             -s, --stats Show queue statistics
183             -T, --tasks List available tasks
184             -t, --task List only jobs for these tasks
185             -U, --unlock Release named lock
186             -w, --workers List workers instead of jobs, or show
187             information for a specific worker
188             -x, --lax Jobs this job depends on may also have failed
189             to allow for it to be processed
190              
191             =head1 DESCRIPTION
192              
193             L manages the L job queue.
194              
195             =head1 ATTRIBUTES
196              
197             L inherits all attributes from L and implements the following new
198             ones.
199              
200             =head2 description
201              
202             my $description = $job->description;
203             $job = $job->description('Foo');
204              
205             Short description of this command, used for the command list.
206              
207             =head2 usage
208              
209             my $usage = $job->usage;
210             $job = $job->usage('Foo');
211              
212             Usage information for this command, used for the help screen.
213              
214             =head1 METHODS
215              
216             L inherits all methods from L and implements the following new
217             ones.
218              
219             =head2 run
220              
221             $job->run(@ARGV);
222              
223             Run this command.
224              
225             =head1 SEE ALSO
226              
227             L, L, L, L, L.
228              
229             =cut