Minion-Backend-API/lib/Minion/Backend/API.pm
package Minion::Backend::API;
use Mojo::Base 'Minion::Backend';
use Mojo::URL;
use Mojo::UserAgent;
use Carp 'croak';
our $VERSION = 1.00;
has 'ua';
has 'url';
has 'authentication';
has 'slow' => 0.5;
has '_url_authentication';
sub broadcast {
my ($self, $command, $args, $ids) = (shift, shift, shift || [], shift || []);
my $res = $self->ua->put(
$self->_url . '/broadcast'
=> json => {
command => $command,
args => $args,
ids => $ids
}
);
$self->_result($res);
}
sub dequeue {
my ($self, $id, $wait, $options) = @_;
# slows down
select(undef, undef, undef, $self->slow);
my $res = $self->ua->post(
$self->_url . '/dequeue'
=> json => {
id => $id,
wait => $wait,
options => $options,
tasks => [keys %{$self->minion->tasks}]
}
);
$self->_result($res);
}
sub enqueue {
my ($self, $task, $args, $options) = (shift, shift, shift || [], shift || {});
my $res = $self->ua->post(
$self->_url . '/enqueue'
=> json => {
task => $task,
args => $args,
options => $options
}
);
$self->_result($res);
}
sub fail_job {
my ($self, $id, $retries, $result) = @_;
my $res = $self->ua->patch(
$self->_url . '/fail-job'
=> json => {
id => $id,
retries => $retries,
result => $result
}
);
$self->_result($res);
}
sub finish_job {
my ($self, $id, $retries, $result) = @_;
my $res = $self->ua->patch(
$self->_url . '/finish-job'
=> json => {
id => $id,
retries => $retries,
result => $result
}
);
$self->_result($res);
}
sub history {
my $self = shift;
my $res = $self->ua->get($self->_url . '/history');
$self->_result($res);
}
sub list_jobs {
my ($self, $offset, $limit, $options) = @_;
my $res = $self->ua->get(
$self->_url . '/list-jobs'
=> json => {
offset => $offset,
limit => $limit,
options => $options
}
);
$self->_result($res);
}
sub list_locks {
my ($self, $offset, $limit, $options) = @_;
my $res = $self->ua->get(
$self->_url . '/list-locks'
=> json => {
offset => $offset,
limit => $limit,
options => $options
}
);
$self->_result($res);
}
sub list_workers {
my ($self, $offset, $limit, $options) = @_;
my $res = $self->ua->get(
$self->_url . '/list-workers'
=> json => {
offset => $offset,
limit => $limit,
options => $options
}
);
$self->_result($res);
}
sub lock {
my ($self, $name, $duration, $options) = (shift, shift, shift, shift // {});
my $res = $self->ua->get(
$self->_url . '/lock'
=> json => {
name => $name,
duration => $duration,
options => $options
}
);
$self->_result($res);
}
sub new {
my ($self, @args) = @_;
my $ua = Mojo::UserAgent->new;
my $authentication;
my $total = scalar(@args);
if ($total > 1) {
for (my $i = 1; $i < $total; $i++) {
$authentication = $args[$i], next if $args[$i] =~ /^[^:]+:[^:]+$/;
$ua = $args[$i] if $args[$i]->isa('Mojo::UserAgent');
}
}
my $url = $args[0];
$url =~ s/\/$//;
return $self->SUPER::new(
ua => $ua,
url => $url,
authentication => $authentication
);
}
sub note {
my ($self, $id, $merge) = @_;
my $res = $self->ua->patch(
$self->_url . '/note'
=> json => {
id => $id,
merge => $merge
}
);
$self->_result($res);
}
sub receive {
my ($self, $id) = @_;
my $res = $self->ua->patch(
$self->_url . '/receive'
=> json => {
id => $id
}
);
$self->_result($res);
}
sub register_worker {
my ($self, $id, $options) = (shift, shift, shift || {});
my $res = $self->ua->post(
$self->_url . '/register-worker'
=> json => {
id => $id,
options => $options
}
);
$self->_result($res);
}
sub remove_job {
my ($self, $id) = @_;
my $res = $self->ua->delete(
$self->_url . '/remove-job'
=> json => {
id => $id
}
);
$self->_result($res);
}
sub repair {
my $self = shift;
my $res = $self->ua->post(
$self->_url . '/repair'
);
$self->_result($res);
}
sub reset {
my ($self, $options) = (shift, shift // {});
my $res = $self->ua->post(
$self->_url . '/reset'
=> json => {
options => $options
}
);
$self->_result($res);
}
sub retry_job {
my ($self, $id, $retries, $options) = (shift, shift, shift, shift || {});
my $res = $self->ua->put(
$self->_url . '/retry-job'
=> json => {
id => $id,
retries => $retries,
options => $options
}
);
$self->_result($res);
}
sub stats {
my $self = shift;
my $res = $self->ua->get($self->_url . '/stats');
$self->_result($res);
}
sub unlock {
my ($self, $name) = @_;
my $res = $self->ua->delete(
$self->_url . '/unlock'
=> json => {
name => $name
}
);
$self->_result($res);
}
sub unregister_worker {
my ($self, $id) = @_;
my $res = $self->ua->delete(
$self->_url . '/unregister-worker'
=> json => {
id => $id
}
);
$self->_result($res);
}
sub _url {
my $self = shift;
return $self->url unless $self->authentication;
# set userinfo if not setted
unless ($self->_url_authentication->isa('Mojo::URL')) {
my $url = Mojo::URL->new($self->url)->userinfo($self->authentication);
$self->_url_authentication($url);
}
return $self->_url_authentication;
}
sub _result {
my ($self, $res) = @_;
my $result = $res->result;
if ($result->is_success) {
my $data = $result->json;
return $data->{result} || undef if $data->{success};
}
croak $result->message if $result->is_error;
return;
}
1;
=encoding utf8
=head1 NAME
Minion::Backend::API - API Rest backend
=head1 SYNOPSIS
# simple
use Minion::Backend::API;
my $backend = Minion::Backend::API->new('https://my-api.com');
# using with your own Mojo::UserAgent
use Mojo::UserAgent;
use Minion::Backend::API;
my $ua = Mojo::UserAgent->new;
my $backend = Minion::Backend::API->new('https://my-api.com', $ua);
# using authentication
my $backend = Minion::Backend::API->new('https://my-api.com', 'user:pass');
my $backend = Minion::Backend::API->new('https://my-api.com', 'user:pass', $ua);
my $backend = Minion::Backend::API->new('https://my-api.com', $ua, 'user:pass');
=head1 DESCRIPTION
L<Minion::Backend::API> is a backend for L<Minion> based on L<Mojo::UserAgent>.
This module need be used together with the module L<Mojolicious::Plugin::Minion::API>,
access it to see manual.
=head1 ATTRIBUTES
L<Minion::Backend::API> inherits all attributes from L<Minion::Backend> and
implements the following new ones.
=head2 url
my $url = $backend->url;
$backend->url('https://my-api.com');
=head2 ua
my $ua = $backend->ua;
$backend->ua(Mojo::UserAgent->new);
=head2 authentication
my $authentication = $backend->authentication;
$backend->authentication('user:pass');
It makes basic authentication.
=head2 slow
$backend->slow(0.2);
Slows down each request of dequeue. Default is 0.5 (half a second).
=head1 SEE MORE OPTIONS
L<Minion::Backend::Pg>
=head1 SEE ALSO
L<Mojolicious::Plugin::Minion::API>, L<Mojo::UserAgent>, L<Minion>, L<Mojolicious::Guides>, L<https://mojolicious.org>.
=head1 AUTHOR
Lucas Tiago de Moraes C<lucastiagodemoraes@gmail.com>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2020 by Lucas Tiago de Moraes.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
=cut