Hello community, here is the log from the commit of package perl-Minion for openSUSE:Factory checked in at 2020-02-04 19:55:44 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/perl-Minion (Old) and /work/SRC/openSUSE:Factory/.perl-Minion.new.26092 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-Minion" Tue Feb 4 19:55:44 2020 rev:54 rq:769858 version:10.04 Changes: -------- --- /work/SRC/openSUSE:Factory/perl-Minion/perl-Minion.changes 2019-12-24 14:30:22.606587757 +0100 +++ /work/SRC/openSUSE:Factory/.perl-Minion.new.26092/perl-Minion.changes 2020-02-04 19:55:44.765405336 +0100 @@ -1,0 +2,15 @@ +Fri Jan 31 03:12:57 UTC 2020 - <timueller+p...@suse.de> + +- updated to 10.04 + see /usr/share/doc/packages/perl-Minion/Changes + + 10.04 2020-01-30 + - Added EXPERIMENTAL total method to Minion::Iterator. + + 10.03 2020-01-29 + - Added EXPERIMENTAL Minion::Iterator module. + - Added EXPERIMENTAL jobs and workers methods to Minion. + - Added EXPERIMENTAL before options to list_jobs and list_workers methods in + Minion::Backend and Minion::Backend::Pg. + +------------------------------------------------------------------- Old: ---- Minion-10.02.tar.gz New: ---- Minion-10.04.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ perl-Minion.spec ++++++ --- /var/tmp/diff_new_pack.WomFRJ/_old 2020-02-04 19:55:45.669405864 +0100 +++ /var/tmp/diff_new_pack.WomFRJ/_new 2020-02-04 19:55:45.673405866 +0100 @@ -1,7 +1,7 @@ # # spec file for package perl-Minion # -# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: perl-Minion -Version: 10.02 +Version: 10.04 Release: 0 %define cpan_name Minion Summary: Job queue @@ -30,8 +30,8 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: perl BuildRequires: perl-macros -BuildRequires: perl(Mojolicious) >= 8.12 -Requires: perl(Mojolicious) >= 8.12 +BuildRequires: perl(Mojolicious) >= 8.27 +Requires: perl(Mojolicious) >= 8.27 %{perl_requires} %description ++++++ Minion-10.02.tar.gz -> Minion-10.04.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.02/Changes new/Minion-10.04/Changes --- old/Minion-10.02/Changes 2019-12-20 20:33:10.000000000 +0100 +++ new/Minion-10.04/Changes 2020-01-30 21:25:48.000000000 +0100 @@ -1,4 +1,13 @@ +10.04 2020-01-30 + - Added EXPERIMENTAL total method to Minion::Iterator. + +10.03 2020-01-29 + - Added EXPERIMENTAL Minion::Iterator module. + - Added EXPERIMENTAL jobs and workers methods to Minion. + - Added EXPERIMENTAL before options to list_jobs and list_workers methods in + Minion::Backend and Minion::Backend::Pg. + 10.02 2019-12-20 - Fixed QUIT signal in Minion::Worker. - Fixed stop remote control command. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.02/MANIFEST new/Minion-10.04/MANIFEST --- old/Minion-10.02/MANIFEST 2019-12-20 21:16:46.000000000 +0100 +++ new/Minion-10.04/MANIFEST 2020-01-31 00:35:29.000000000 +0100 @@ -18,6 +18,7 @@ lib/Minion/Command/minion.pm lib/Minion/Command/minion/job.pm lib/Minion/Command/minion/worker.pm +lib/Minion/Iterator.pm lib/Minion/Job.pm lib/Minion/Worker.pm lib/Mojolicious/Plugin/Minion.pm diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.02/META.json new/Minion-10.04/META.json --- old/Minion-10.02/META.json 2019-12-20 21:16:46.000000000 +0100 +++ new/Minion-10.04/META.json 2020-01-31 00:35:29.000000000 +0100 @@ -4,7 +4,7 @@ "Sebastian Riedel <s...@cpan.org>" ], "dynamic_config" : 0, - "generated_by" : "ExtUtils::MakeMaker version 7.42, CPAN::Meta::Converter version 2.150010", + "generated_by" : "ExtUtils::MakeMaker version 7.44, CPAN::Meta::Converter version 2.150010", "license" : [ "artistic_2" ], @@ -33,7 +33,7 @@ }, "runtime" : { "requires" : { - "Mojolicious" : "8.12", + "Mojolicious" : "8.27", "perl" : "5.010001" } } @@ -54,6 +54,6 @@ }, "x_IRC" : "irc://irc.freenode.net/#mojo" }, - "version" : "10.02", + "version" : "10.04", "x_serialization_backend" : "JSON::PP version 4.04" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.02/META.yml new/Minion-10.04/META.yml --- old/Minion-10.02/META.yml 2019-12-20 21:16:46.000000000 +0100 +++ new/Minion-10.04/META.yml 2020-01-31 00:35:29.000000000 +0100 @@ -7,7 +7,7 @@ configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 0 -generated_by: 'ExtUtils::MakeMaker version 7.42, CPAN::Meta::Converter version 2.150010' +generated_by: 'ExtUtils::MakeMaker version 7.44, CPAN::Meta::Converter version 2.150010' license: artistic_2 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html @@ -19,7 +19,7 @@ - inc - t requires: - Mojolicious: '8.12' + Mojolicious: '8.27' perl: '5.010001' resources: IRC: irc://irc.freenode.net/#mojo @@ -27,5 +27,5 @@ homepage: https://mojolicious.org license: http://www.opensource.org/licenses/artistic-license-2.0 repository: https://github.com/mojolicious/minion.git -version: '10.02' +version: '10.04' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.02/Makefile.PL new/Minion-10.04/Makefile.PL --- old/Minion-10.02/Makefile.PL 2019-12-16 12:46:50.000000000 +0100 +++ new/Minion-10.04/Makefile.PL 2020-01-29 00:33:49.000000000 +0100 @@ -28,6 +28,6 @@ x_IRC => 'irc://irc.freenode.net/#mojo' }, }, - PREREQ_PM => {Mojolicious => '8.12'}, + PREREQ_PM => {Mojolicious => '8.27'}, test => {TESTS => 't/*.t t/*/*.t'} ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.02/lib/Minion/Backend/Pg.pm new/Minion-10.04/lib/Minion/Backend/Pg.pm --- old/Minion-10.02/lib/Minion/Backend/Pg.pm 2019-12-16 13:00:40.000000000 +0100 +++ new/Minion-10.04/lib/Minion/Backend/Pg.pm 2020-01-29 23:04:49.000000000 +0100 @@ -89,12 +89,13 @@ extract(epoch from started) as started, state, task, extract(epoch from now()) as time, count(*) over() as total, worker from minion_jobs as j - where (id = any ($1) or $1 is null) and (notes \? any ($2) or $2 is null) - and (queue = any ($3) or $3 is null) and (state = any ($4) or $4 is null) - and (task = any ($5) or $5 is null) + where (id < $1 or $1 is null) and (id = any ($2) or $2 is null) + and (notes \? any ($3) or $3 is null) + and (queue = any ($4) or $4 is null) and (state = any ($5) or $5 is null) + and (task = any ($6) or $6 is null) order by id desc - limit $6 offset $7', @$options{qw(ids notes queues states tasks)}, $limit, - $offset + limit $7 offset $8', @$options{qw(before ids notes queues states tasks)}, + $limit, $offset )->expand->hashes->to_array; return _total('jobs', $jobs); @@ -122,8 +123,9 @@ ) as jobs, host, pid, status, extract(epoch from started) as started, count(*) over() as total from minion_workers - where (id = any (\$1) or \$1 is null) - order by id desc limit \$2 offset \$3", $options->{ids}, $limit, $offset + where (id < \$1 or \$1 is null) and (id = any (\$2) or \$2 is null) + order by id desc limit \$3 offset \$4", @$options{qw(before ids)}, $limit, + $offset )->expand->hashes->to_array; return _total('workers', $workers); } @@ -541,6 +543,13 @@ =over 2 +=item before + + before => 23 + +List only jobs before this id. Note that this option is EXPERIMENTAL and might +change without warning! + =item ids ids => ['23', '24'] @@ -756,6 +765,13 @@ =over 2 +=item before + + before => 23 + +List only workers before this id. Note that this option is EXPERIMENTAL and +might change without warning! + =item ids ids => ['23', '24'] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.02/lib/Minion/Backend.pm new/Minion-10.04/lib/Minion/Backend.pm --- old/Minion-10.02/lib/Minion/Backend.pm 2019-12-16 12:46:50.000000000 +0100 +++ new/Minion-10.04/lib/Minion/Backend.pm 2020-01-29 22:32:26.000000000 +0100 @@ -268,6 +268,13 @@ =over 2 +=item before + + before => 23 + +List only jobs before this id. Note that this option is EXPERIMENTAL and might +change without warning! + =item ids ids => ['23', '24'] @@ -485,6 +492,13 @@ =over 2 +=item before + + before => 23 + +List only workers before this id. Note that this option is EXPERIMENTAL and +might change without warning! + =item ids ids => ['23', '24'] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.02/lib/Minion/Iterator.pm new/Minion-10.04/lib/Minion/Iterator.pm --- old/Minion-10.02/lib/Minion/Iterator.pm 1970-01-01 01:00:00.000000000 +0100 +++ new/Minion-10.04/lib/Minion/Iterator.pm 2020-01-30 22:36:10.000000000 +0100 @@ -0,0 +1,98 @@ +package Minion::Iterator; +use Mojo::Base -base; + +has fetch => 10; +has [qw(minion options what)]; + +sub next { shift @{shift->_fetch(0)->{results}} } + +sub total { shift->_fetch(1)->{total} } + +sub _fetch { + my ($self, $lazy) = @_; + + return $self if ($lazy && exists $self->{total}) || @{$self->{results} // []}; + + my $what = $self->{jobs} ? 'jobs' : 'workers'; + my $method = "list_$what"; + my $options = $self->options; + my $results = $self->minion->backend->$method(0, $self->fetch, $options); + + $self->{total} = $results->{total} + ($self->{count} // 0); + $self->{count} += my @results = @{$results->{$what}}; + push @{$self->{results}}, @results; + $options->{before} = $results[-1]{id} if @results; + + return $self; +} + +1; + +=encoding utf8 + +=head1 NAME + +Minion::Iterator - Minion iterator + +=head1 SYNOPSIS + + use Minion::Iterator; + + my $iter = Minion::Iterator->new( + minion => $minion, options => {states => ['inactive']}); + +=head1 DESCRIPTION + +L<Minion::Iterator> is an iterator for L<Minion> listing methods. Note that this +module is EXPERIMENTAL and might change without warning! + +=head1 ATTRIBUTES + +L<Minion::Iterator> implements the following attributes. + +=head2 fetch + + my $fetch = $iter->fetch; + $iter = $iter->fetch(2); + +Number of results to cache, defaults to C<10>. + +=head2 minion + + my $minion = $iter->minion; + $iter = $iter->minion(Minion->new); + +L<Minion> object this job belongs to. + +=head2 options + + my $options = $iter->options; + $iter = $iter->options({states => ['inactive']}); + +Options to be passed to L<Minion::Backend/"list_jobs"> or +L<Minion::Backend/"list_workers">. + +=head1 METHODS + +L<Minion::Iterator> inherits all methods from L<Mojo::Base> and implements the +following new ones. + +=head2 next + + my $value = $iter->next; + +Get next value. + +=head2 total + + my $num = $iter->total; + +Total number of results. If results are removed in the backend while iterating, +this number will become an estimate that gets updated every time new results are +fetched. + +=head1 SEE ALSO + +L<Minion>, L<Mojolicious::Guides>, L<https://mojolicious.org>. + +=cut diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.02/lib/Minion.pm new/Minion-10.04/lib/Minion.pm --- old/Minion-10.02/lib/Minion.pm 2019-12-20 01:56:53.000000000 +0100 +++ new/Minion-10.04/lib/Minion.pm 2020-01-30 22:33:57.000000000 +0100 @@ -3,6 +3,7 @@ use Carp 'croak'; use Config; +use Minion::Iterator; use Minion::Job; use Minion::Worker; use Mojo::Date; @@ -10,7 +11,7 @@ use Mojo::Loader 'load_class'; use Mojo::Promise; use Mojo::Server; -use Mojo::Util 'steady_time'; +use Mojo::Util qw(scope_guard steady_time); has app => @@ -22,7 +23,7 @@ has remove_after => 172800; has tasks => sub { {} }; -our $VERSION = '10.02'; +our $VERSION = '10.04'; sub add_task { ($_[0]->tasks->{$_[1]} = $_[2]) and return $_[0] } @@ -59,7 +60,7 @@ my ($self, $name, $duration, $options) = @_; my $time = steady_time + $duration; return undef unless $self->lock($name, $duration, $options); - return Minion::_Guard->new(minion => $self, name => $name, time => $time); + return scope_guard sub { $self->unlock($name) if steady_time < $time }; } sub history { shift->backend->history } @@ -77,6 +78,8 @@ ); } +sub jobs { shift->_iterator(1, @_) } + sub lock { shift->backend->lock(@_) } sub new { @@ -126,6 +129,8 @@ return $worker; } +sub workers { shift->_iterator(0, @_) } + sub _backoff { (shift()**4) + 15 } # Used by the job command and admin plugin @@ -142,6 +147,12 @@ return $self; } +sub _iterator { + my ($self, $jobs, $options) = (shift, shift, shift // {}); + return Minion::Iterator->new(minion => $self, options => $options, + jobs => $jobs); +} + sub _info { shift->backend->list_jobs(0, 1, {ids => [shift]})->{jobs}[0] } sub _result { @@ -151,13 +162,6 @@ elsif ($job->{state} eq 'failed') { $promise->reject($job) } } -package Minion::_Guard; -use Mojo::Base -base; - -use Mojo::Util 'steady_time'; - -sub DESTROY { $_[0]{minion}->unlock($_[0]{name}) if steady_time < $_[0]{time} } - 1; =encoding utf8 @@ -586,6 +590,186 @@ # Get job result my $result = $minion->job($id)->info->{result}; +=head2 jobs + + my $jobs = $minion->jobs; + my $jobs = $minion->jobs({states => ['inactive']}); + +Return L<Minion::Iterator> object to safely iterate through job information. +Note that this method is EXPERIMENTAL and might change without warning! + + # Iterate through jobs for two tasks + my $jobs = $minion->jobs({tasks => ['foo', 'bar']}); + while (my $info = $jobs->next) { + say "$info->{id}: $info->{state}"; + } + + # Remove all failed jobs from a named queue + my $jobs = $minion->jobs({states => ['failed'], queues => ['unimportant']}); + while (my $info = $jobs->next) { + $minion->job($info->{id})->remove; + } + + # Count failed jobs for a task + say $minion->jobs({states => ['failed'], tasks => ['foo']})->total; + +These options are currently available: + +=over 2 + +=item ids + + ids => ['23', '24'] + +List only jobs with these ids. + +=item notes + + notes => ['foo', 'bar'] + +List only jobs with one of these notes. Note that this option is EXPERIMENTAL +and might change without warning! + +=item queues + + queues => ['important', 'unimportant'] + +List only jobs in these queues. + +=item states + + states => ['inactive', 'active'] + +List only jobs in these states. + +=item tasks + + tasks => ['foo', 'bar'] + +List only jobs for these tasks. + +=back + +These fields are currently available: + +=over 2 + +=item args + + args => ['foo', 'bar'] + +Job arguments. + +=item attempts + + attempts => 25 + +Number of times performing this job will be attempted. + +=item children + + children => ['10026', '10027', '10028'] + +Jobs depending on this job. + +=item created + + created => 784111777 + +Epoch time job was created. + +=item delayed + + delayed => 784111777 + +Epoch time job was delayed to. + +=item finished + + finished => 784111777 + +Epoch time job was finished. + +=item id + + id => 10025 + +Job id. + +=item notes + + notes => {foo => 'bar', baz => [1, 2, 3]} + +Hash reference with arbitrary metadata for this job. + +=item parents + + parents => ['10023', '10024', '10025'] + +Jobs this job depends on. + +=item priority + + priority => 3 + +Job priority. + +=item queue + + queue => 'important' + +Queue name. + +=item result + + result => 'All went well!' + +Job result. + +=item retried + + retried => 784111777 + +Epoch time job has been retried. + +=item retries + + retries => 3 + +Number of times job has been retried. + +=item started + + started => 784111777 + +Epoch time job was started. + +=item state + + state => 'inactive' + +Current job state, usually C<active>, C<failed>, C<finished> or C<inactive>. + +=item task + + task => 'foo' + +Task name. + +=item time + + time => 78411177 + +Server time. + +=item worker + + worker => '154' + +Id of worker that is processing the job. + +=back + =head2 lock my $bool = $minion->lock('foo', 3600); @@ -860,6 +1044,80 @@ } while keys %jobs; $worker->unregister; +=head2 workers + + my $workers = $minion->workers; + my $workers = $minion->workers({ids => [2, 3]}); + +Return L<Minion::Iterator> object to safely iterate through worker information. +Note that this method is EXPERIMENTAL and might change without warning! + + # Iterate through workers + my $workers = $minion->workers; + while (my $info = $workers->next) { + say "$info->{id}: $info->{host}"; + } + +These options are currently available: + +=over 2 + +=item ids + + ids => ['23', '24'] + +List only workers with these ids. + +=back + +These fields are currently available: + +=over 2 + +=item id + + id => 22 + +Worker id. + +=item host + + host => 'localhost' + +Worker host. + +=item jobs + + jobs => ['10023', '10024', '10025', '10029'] + +Ids of jobs the worker is currently processing. + +=item notified + + notified => 784111777 + +Epoch time worker sent the last heartbeat. + +=item pid + + pid => 12345 + +Process id of worker. + +=item started + + started => 784111777 + +Epoch time worker was started. + +=item status + + status => {queues => ['default', 'important']} + +Hash reference with whatever status information the worker would like to share. + +=back + =head1 REFERENCE This is the class hierarchy of the L<Minion> distribution. @@ -972,7 +1230,7 @@ =head1 COPYRIGHT AND LICENSE -Copyright (C) 2014-2019, Sebastian Riedel and others. +Copyright (C) 2014-2020, Sebastian Riedel and others. This program is free software, you can redistribute it and/or modify it under the terms of the Artistic License version 2.0. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.02/t/pg.t new/Minion-10.04/t/pg.t --- old/Minion-10.02/t/pg.t 2019-12-16 13:43:58.000000000 +0100 +++ new/Minion-10.04/t/pg.t 2020-01-30 21:25:21.000000000 +0100 @@ -82,7 +82,7 @@ # Job results (already finished) (@finished, @failed) = (); $minion->result_p($id)->then(sub { @finished = @_ }) - ->catch(sub { @failed = @_ })->wait; + ->catch(sub { @failed = @_ })->wait; is_deeply $finished[0]{result}, {just => 'works!'}, 'right result'; is_deeply $finished[0]{notes}, {foo => 'bar'}, 'right note'; ok !$finished[1], 'no more results'; @@ -92,7 +92,7 @@ (@finished, @failed) = (); $minion->job($id)->retry; $minion->result_p($id)->timeout(0.25)->then(sub { @finished = @_ }) - ->catch(sub { @failed = @_ })->wait; + ->catch(sub { @failed = @_ })->wait; is_deeply \@finished, [], 'not finished'; is_deeply \@failed, ['Promise timeout'], 'failed'; Mojo::IOLoop->start; @@ -101,7 +101,7 @@ (@finished, @failed) = (); $minion->job($id)->remove; $minion->result_p($id)->then(sub { @finished = (@_, 'finished') }) - ->catch(sub { @failed = (@_, 'failed') })->wait; + ->catch(sub { @failed = (@_, 'failed') })->wait; is_deeply \@finished, ['finished'], 'job no longer exists'; is_deeply \@failed, [], 'not failed'; @@ -141,8 +141,8 @@ # Repair abandoned job in minion_foreground queue (have to be handled manually) $worker->register; -$id = $minion->enqueue('test', [], {queue => 'minion_foreground'}); -$job = $worker->dequeue(0, {queues => ['minion_foreground']}); +$id = $minion->enqueue('test', [], {queue => 'minion_foreground'}); +$job = $worker->dequeue(0, {queues => ['minion_foreground']}); is $job->id, $id, 'right id'; $worker->unregister; $minion->repair; @@ -205,6 +205,46 @@ $worker->unregister; $worker2->unregister; +# Iterate workers +$minion->reset({all => 1}); +$worker = $minion->worker->status({test => 'one'})->register; +$worker2 = $minion->worker->status({test => 'two'})->register; +my $worker3 = $minion->worker->status({test => 'three'})->register; +my $worker4 = $minion->worker->status({test => 'four'})->register; +my $worker5 = $minion->worker->status({test => 'five'})->register; +my $workers = $minion->workers->fetch(2); +is $workers->options->{before}, undef, 'no before'; +is $workers->next->{status}{test}, 'five', 'right status'; +is $workers->options->{before}, 4, 'before 4'; +is $workers->next->{status}{test}, 'four', 'right status'; +is $workers->next->{status}{test}, 'three', 'right status'; +is $workers->options->{before}, 2, 'before 2'; +is $workers->next->{status}{test}, 'two', 'right status'; +is $workers->next->{status}{test}, 'one', 'right status'; +is $workers->options->{before}, 1, 'before 1'; +is $workers->next, undef, 'no more results'; +$workers = $minion->workers({ids => [2, 4, 1]}); +is $workers->options->{before}, undef, 'no before'; +is $workers->next->{status}{test}, 'four', 'right status'; +is $workers->options->{before}, 1, 'before 1'; +is $workers->next->{status}{test}, 'two', 'right status'; +is $workers->next->{status}{test}, 'one', 'right status'; +is $workers->next, undef, 'no more results'; +$workers = $minion->workers->fetch(2); +is $workers->next->{status}{test}, 'five', 'right status'; +is $workers->next->{status}{test}, 'four', 'right status'; +is $workers->total, 5, 'five workers'; +$worker5->unregister; +$worker4->unregister; +$worker3->unregister; +is $workers->next->{status}{test}, 'two', 'right status'; +is $workers->next->{status}{test}, 'one', 'right status'; +is $workers->next, undef, 'no more results'; +is $workers->total, 4, 'four workers'; +is $minion->workers->total, 2, 'two workers'; +$worker->unregister; +$worker2->unregister; + # Exclusive lock ok $minion->lock('foo', 3600), 'locked'; ok !$minion->lock('foo', 3600), 'not locked again'; @@ -217,7 +257,7 @@ ok !$minion->lock('foo', 3600), 'not locked again'; ok $minion->unlock('foo'), 'unlocked'; ok !$minion->unlock('foo'), 'not unlocked again'; -ok $minion->lock('yada', 3600, {limit => 1}), 'locked'; +ok $minion->lock('yada', 3600, {limit => 1}), 'locked'; ok !$minion->lock('yada', 3600, {limit => 1}), 'not locked again'; # Shared lock @@ -226,7 +266,7 @@ ok $minion->lock('bar', -3600, {limit => 3}), 'locked again'; ok $minion->lock('bar', 3600, {limit => 3}), 'locked again'; ok !$minion->lock('bar', 3600, {limit => 2}), 'not locked again'; -ok $minion->lock('baz', 3600, {limit => 3}), 'locked'; +ok $minion->lock('baz', 3600, {limit => 3}), 'locked'; ok $minion->unlock('bar'), 'unlocked'; ok $minion->lock('bar', 3600, {limit => 3}), 'locked again'; ok $minion->unlock('bar'), 'unlocked again'; @@ -287,6 +327,7 @@ undef $guard3; # Reset (locks) +$minion->enqueue('test'); $minion->lock('test', 3600); $minion->worker->register; ok $minion->backend->list_jobs(0, 1)->{total}, 'jobs'; @@ -384,7 +425,9 @@ $job->remove; # List jobs -$id = $minion->enqueue('add'); +$id = $minion->enqueue('add'); +is $minion->backend->list_jobs(1, 1)->{total}, 4, + 'four total with offset and limit'; $results = $minion->backend->list_jobs(0, 10); $batch = $results->{jobs}; is $results->{total}, 4, 'four jobs total'; @@ -394,7 +437,7 @@ is $batch->[0]{retries}, 0, 'job has not been retried'; like $batch->[0]{created}, qr/^[\d.]+$/, 'has created timestamp'; is $batch->[1]{task}, 'fail', 'right task'; -is_deeply $batch->[1]{args}, [], 'right arguments'; +is_deeply $batch->[1]{args}, [], 'right arguments'; is_deeply $batch->[1]{notes}, {}, 'right metadata'; is_deeply $batch->[1]{result}, ['works'], 'right result'; is $batch->[1]{state}, 'finished', 'right state'; @@ -434,7 +477,7 @@ is $batch->[2]{queue}, 'default', 'right queue'; is $batch->[3]{queue}, 'default', 'right queue'; ok !$batch->[4], 'no more results'; -$id2 = $minion->enqueue('test' => [] => {notes => {is_test => 1}}); +$id2 = $minion->enqueue('test' => [] => {notes => {is_test => 1}}); $batch = $minion->backend->list_jobs(0, 10, {notes => ['is_test']})->{jobs}; is $batch->[0]{task}, 'test', 'right task'; ok !$batch->[4], 'no more results'; @@ -452,7 +495,47 @@ is $batch->[0]{state}, 'finished', 'right state'; is $batch->[0]{retries}, 1, 'job has been retried'; ok !$batch->[1], 'no more results'; -ok $minion->job($id)->remove, 'job removed'; + +# Iterate jobs +my $jobs = $minion->jobs; +is $jobs->next->{task}, 'add', 'right task'; +is $jobs->options->{before}, 1, 'before 1'; +is $jobs->next->{task}, 'fail', 'right task'; +is $jobs->next->{task}, 'fail', 'right task'; +is $jobs->next->{task}, 'fail', 'right task'; +is $jobs->next, undef, 'no more results'; +is $jobs->total, 4, 'four jobs'; +$jobs = $minion->jobs->fetch(2); +is $jobs->options->{before}, undef, 'no before'; +is $jobs->next->{task}, 'add', 'right task'; +is $jobs->options->{before}, 3, 'before 3'; +is $jobs->next->{task}, 'fail', 'right task'; +is $jobs->options->{before}, 3, 'before 3'; +is $jobs->next->{task}, 'fail', 'right task'; +is $jobs->options->{before}, 1, 'before 1'; +is $jobs->next->{task}, 'fail', 'right task'; +is $jobs->options->{before}, 1, 'before 1'; +is $jobs->next, undef, 'no more results'; +is $jobs->total, 4, 'four jobs'; +$jobs = $minion->jobs({states => ['inactive']}); +is $jobs->total, 1, 'one job'; +is $jobs->next->{task}, 'add', 'right task'; +is $jobs->next, undef, 'no more results'; +$jobs = $minion->jobs({states => ['active']}); +is $jobs->next, undef, 'no more results'; +$jobs = $minion->jobs->fetch(1); +is $jobs->next->{task}, 'add', 'right task'; +is $jobs->total, 4, 'four jobs'; +$id2 = $minion->enqueue('add'); +my $next = $jobs->next; +is $next->{task}, 'fail', 'right task'; +ok $minion->job($next->{id} - 1)->remove, 'job removed'; +is $jobs->total, 4, 'four jobs'; +is $jobs->next->{task}, 'fail', 'right task'; +is $jobs->next, undef, 'no more results'; +is $jobs->total, 3, 'three jobs'; +ok $minion->job($id)->remove, 'job removed'; +ok $minion->job($id2)->remove, 'job removed'; # Enqueue, dequeue and perform is $minion->job(12345), undef, 'job does not exist'; @@ -701,13 +784,13 @@ $job = $worker->dequeue(0); is $job->id, $id, 'right id'; ok $job->fail('Something bad happened!'), 'job failed'; -is $job->info->{state}, 'failed', 'right state'; +is $job->info->{state}, 'failed', 'right state'; is $job->info->{result}, 'Something bad happened!', 'right result'; $id = $minion->enqueue('fail'); $job = $worker->dequeue(0); is $job->id, $id, 'right id'; $job->perform; -is $job->info->{state}, 'failed', 'right state'; +is $job->info->{state}, 'failed', 'right state'; is $job->info->{result}, "Intentional failure!\n", 'right result'; $worker->unregister; @@ -755,7 +838,7 @@ $job = $worker->register->dequeue(0); is $job->id, $id, 'right id'; $job->perform; -is $job->info->{state}, 'failed', 'right state'; +is $job->info->{state}, 'failed', 'right state'; is $job->info->{result}, 'Non-zero exit status (1)', 'right result'; $worker->unregister; @@ -883,7 +966,7 @@ ok !$job->is_finished, 'job is not finished'; $job->stop; usleep 5000 until $job->is_finished; -is $job->info->{state}, 'failed', 'right state'; +is $job->info->{state}, 'failed', 'right state'; like $job->info->{result}, qr/Non-zero exit status/, 'right result'; $minion->enqueue('long_running'); $job = $worker->dequeue(0); @@ -895,7 +978,7 @@ is $job->info->{state}, 'active', 'right state'; $job->kill('INT'); usleep 5000 until $job->is_finished; -is $job->info->{state}, 'failed', 'right state'; +is $job->info->{state}, 'failed', 'right state'; like $job->info->{result}, qr/Non-zero exit status/, 'right result'; $worker->unregister;