File Coverage

blib/lib/Mojolicious/Plugin/Minion/API.pm
Criterion Covered Total %
statement 118 126 93.6
branch 2 4 50.0
condition 4 11 36.3
subroutine 27 28 96.4
pod 1 1 100.0
total 152 170 89.4


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::Minion::API;
2 1     1   92272 use Mojo::Base 'Mojolicious::Plugin';
  1         4  
  1         5  
3              
4 1     1   157 use Carp 'croak';
  1         3  
  1         2045  
5              
6             sub register {
7 1     1 1 43 my ($self, $app, $config) = @_;
8            
9             # minion required
10 1   0     8 $config->{minion} ||= eval { $app->minion } || croak 'A minion instance is required';
      33        
11            
12             # set helper backend
13             $app->helper('backend' => sub {
14 20     20   1733 return $config->{minion}->backend;
15 1         9 });
16            
17             # save tasks
18             $app->hook(before_routes => sub {
19 20     20   181900 my $c = shift;
20            
21 20 50 66     59 if ($c->req->json && $c->req->json->{tasks}) {
22 0         0 $config->{minion}->tasks->{$_} = 1 for @{$c->req->json->{tasks}};
  0         0  
23             }
24 1         110 });
25            
26             # enable all origin
27             $app->hook(before_render => sub {
28 20     20   508 shift->res->headers->header('Access-Control-Allow-Origin' => '*');
29 1         24 });
30            
31             # global
32             $app->routes->options('/:all' => [all => qr/.+/] => sub {
33 0     0   0 my $c = shift;
34            
35             # headers
36 0         0 $c->res->headers->header('Access-Control-Allow-Origin' => '*');
37 0         0 $c->res->headers->header('Access-Control-Allow-Credentials' => 'true');
38 0         0 $c->res->headers->header('Access-Control-Allow-Methods' => 'OPTIONS, GET, POST, DELETE, PUT, PATCH');
39 0         0 $c->res->headers->header('Access-Control-Allow-Headers' => 'Content-Type, Authorization');
40            
41             # return status 200 to options
42 0         0 $c->respond_to(any => {data => '', status => 200});
43 1         15 });
44            
45             # router api
46 1 50       486 my $api = $app->routes->under($config->{pattern} ? $config->{pattern} : '/');
47            
48             # broadcast
49             $api->put('/broadcast' => sub {
50 1     1   1699 my $c = shift;
51            
52 1         28 my $command = $c->req->json->{command};
53 1         32 my $args = $c->req->json->{args};
54 1         27 my $ids = $c->req->json->{ids};
55            
56 1         32 &_render($c, $app->backend->broadcast($command, $args, $ids));
57 1         176 });
58            
59             # dequeue
60             $api->post('/dequeue' => sub {
61 1     1   1301 my $c = shift;
62            
63 1         15 my $id = $c->req->json->{id};
64 1         28 my $wait = $c->req->json->{wait};
65 1         24 my $options = $c->req->json->{options};
66            
67 1         21 &_render($c, $app->backend->dequeue($id, $wait, $options));
68 1         276 });
69            
70             # enqueue
71             $api->post('/enqueue' => sub {
72 1     1   1318 my $c = shift;
73            
74 1         3 my $task = $c->req->json->{task};
75 1         25 my $args = $c->req->json->{args};
76 1         20 my $options = $c->req->json->{options};
77            
78 1         21 &_render($c, $app->backend->enqueue($task, $args, $options));
79 1         257 });
80            
81             # fail_job
82             $api->patch('/fail-job' => sub {
83 1     1   1159 my $c = shift;
84            
85 1         5 my $id = $c->req->json->{id};
86 1         24 my $retries = $c->req->json->{retries};
87 1         19 my $result = $c->req->json->{result};
88            
89 1         21 &_render($c, $app->backend->fail_job($id, $retries, $result));
90 1         290 });
91            
92             # finish_job
93             $api->patch('/finish-job' => sub {
94 1     1   1302 my $c = shift;
95            
96 1         7 my $id = $c->req->json->{id};
97 1         27 my $retries = $c->req->json->{retries};
98 1         19 my $result = $c->req->json->{result};
99            
100 1         21 &_render($c, $app->backend->finish_job($id, $retries, $result));
101 1         257 });
102            
103             # history
104             $api->get('/history' => sub {
105 1     1   2229 my $c = shift;
106            
107 1         5 &_render($c, $app->backend->history);
108 1         313 });
109            
110             # list_jobs
111             $api->get('/list-jobs' => sub {
112 1     1   1351 my $c = shift;
113            
114 1         4 my $offset = $c->req->json->{offset};
115 1         26 my $limit = $c->req->json->{limit};
116 1         18 my $options = $c->req->json->{options};
117            
118 1         20 &_render($c, $app->backend->list_jobs($offset, $limit, $options));
119 1         416 });
120            
121             # list_locks
122             $api->get('/list-locks' => sub {
123 1     1   1310 my $c = shift;
124            
125 1         5 my $offset = $c->req->json->{offset};
126 1         25 my $limit = $c->req->json->{limit};
127 1         19 my $options = $c->req->json->{options};
128            
129 1         20 &_render($c, $app->backend->list_locks($offset, $limit, $options));
130 1         333 });
131            
132             # list_workers
133             $api->get('/list-workers' => sub {
134 1     1   1448 my $c = shift;
135            
136 1         5 my $offset = $c->req->json->{offset};
137 1         26 my $limit = $c->req->json->{limit};
138 1         19 my $options = $c->req->json->{options};
139            
140 1         19 &_render($c, $app->backend->list_workers($offset, $limit, $options));
141 1         275 });
142            
143             # lock
144             $api->get('/lock' => sub {
145 1     1   1752 my $c = shift;
146            
147 1         5 my $name = $c->req->json->{name};
148 1         28 my $duration = $c->req->json->{duration};
149 1         20 my $options = $c->req->json->{options};
150            
151 1         19 &_render($c, $app->backend->lock($name, $duration, $options));
152 1         271 });
153            
154             # note
155             $api->patch('/note' => sub {
156 1     1   1403 my $c = shift;
157            
158 1         5 my $id = $c->req->json->{id};
159 1         24 my $merge = $c->req->json->{merge};
160            
161 1         20 &_render($c, $app->backend->note($id, $merge));
162 1         244 });
163            
164             # receive
165             $api->patch('/receive' => sub {
166 1     1   1494 my $c = shift;
167            
168 1         5 my $id = $c->req->json->{id};
169            
170 1         25 &_render($c, $app->backend->receive($id));
171 1         409 });
172            
173             # register_worker
174             $api->post('/register-worker' => sub {
175 1     1   1513 my $c = shift;
176            
177 1         4 my $id = $c->req->json->{id};
178 1         25 my $options = $c->req->json->{options};
179            
180 1         19 &_render($c, $app->backend->register_worker($id, $options));
181 1         267 });
182            
183             # remove_job
184             $api->delete('/remove-job' => sub {
185 1     1   1604 my $c = shift;
186            
187 1         4 my $id = $c->req->json->{id};
188            
189 1         26 &_render($c, $app->backend->remove_job($id));
190 1         289 });
191            
192             # repair
193             $api->post('/repair' => sub {
194 1     1   2486 my $c = shift;
195            
196 1         6 &_render($c, $app->backend->repair);
197 1         285 });
198            
199             # reset
200             $api->post('/reset' => sub {
201 1     1   1612 my $c = shift;
202            
203 1         5 my $options = $c->req->json->{options};
204            
205 1         27 &_render($c, $app->backend->reset($options));
206 1         263 });
207            
208             # retry_job
209             $api->put('/retry-job' => sub {
210 1     1   1645 my $c = shift;
211            
212 1         5 my $id = $c->req->json->{id};
213 1         26 my $retries = $c->req->json->{retries};
214 1         19 my $options = $c->req->json->{options};
215            
216 1         20 &_render($c, $app->backend->retry_job($id, $retries, $options));
217 1         266 });
218            
219             # stats
220             $api->get('/stats' => sub {
221 1     1   1644 my $c = shift;
222            
223 1         5 &_render($c, $app->backend->stats);
224 1         286 });
225            
226             # unlock
227             $api->delete('/unlock' => sub {
228 1     1   1746 my $c = shift;
229            
230 1         5 my $name = $c->req->json->{name};
231            
232 1         26 &_render($c, $app->backend->unlock($name));
233 1         235 });
234            
235             # unregister_worker
236             $api->delete('/unregister-worker' => sub {
237 1     1   1869 my $c = shift;
238            
239 1         5 my $id = $c->req->json->{id};
240            
241 1         26 &_render($c, $app->backend->unregister_worker($id));
242 1         262 });
243             }
244              
245             sub _render {
246 20     20   203 my ($c, $result) = @_;
247            
248 20   50     142 $c->render(
249             json => {
250             success => 1,
251             result => $result || ''
252             }
253             );
254             }
255              
256             1;
257              
258             =encoding utf8
259              
260             =head1 NAME
261              
262             Mojolicious::Plugin::Minion::API
263              
264             =head1 SYNOPSIS
265              
266             use Mojolicious::Lite;
267             use Minion;
268            
269             plugin 'Minion::API' => {
270             minion => Minion->new(Pg => 'postgresql://postgres@/test')
271             };
272            
273             app->start;
274            
275             =head1 DESCRIPTION
276              
277             L is a plugin L.
278             This module provides an API to receive request from L
279              
280             =head1 OPTIONS
281              
282             L supports the following options.
283              
284             =head2 minion
285            
286             # Mojolicious::Lite
287             plugin 'Minion' => {
288             mysql => 'mysql://user@127.0.0.1/minion_jobs'
289             };
290            
291             plugin 'Minion::API' => {
292             minion => app->minion
293             };
294            
295             L object to handle backend, this option is mandatory.
296              
297             =head2 pattern
298            
299             # Mojolicious::Lite
300             plugin 'Minion::API' => {
301             pattern => '/minion-api' # https://my-api.com/minion-api
302             };
303            
304             This option is to set pattern in url, see more L
305              
306             =head1 SEE ALSO
307            
308             L, L, L, L.
309              
310             =head1 AUTHOR
311            
312             Lucas Tiago de Moraes C
313            
314             =head1 COPYRIGHT AND LICENSE
315            
316             This software is copyright (c) 2020 by Lucas Tiago de Moraes.
317            
318             This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
319            
320             =cut