Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package perl-Minion for openSUSE:Factory checked in at 2021-03-16 15:46:39 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/perl-Minion (Old) and /work/SRC/openSUSE:Factory/.perl-Minion.new.2401 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-Minion" Tue Mar 16 15:46:39 2021 rev:67 rq:879421 version:10.20 Changes: -------- --- /work/SRC/openSUSE:Factory/perl-Minion/perl-Minion.changes 2021-03-11 20:12:48.412713708 +0100 +++ /work/SRC/openSUSE:Factory/.perl-Minion.new.2401/perl-Minion.changes 2021-03-16 15:47:06.889294880 +0100 @@ -1,0 +2,11 @@ +Mon Mar 15 03:09:40 UTC 2021 - Tina M??ller <timueller+p...@suse.de> + +- updated to 10.20 + see /usr/share/doc/packages/perl-Minion/Changes + + 10.20 2021-03-13 + - Removed experimental status from expiring jobs feature. + - Added Minion::Guide. + - Improved admin ui and job command to use YAML::XS to make job information easier to read. + +------------------------------------------------------------------- Old: ---- Minion-10.19.tar.gz New: ---- Minion-10.20.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ perl-Minion.spec ++++++ --- /var/tmp/diff_new_pack.Pk3Sd7/_old 2021-03-16 15:47:07.313295538 +0100 +++ /var/tmp/diff_new_pack.Pk3Sd7/_new 2021-03-16 15:47:07.317295545 +0100 @@ -18,7 +18,7 @@ %define cpan_name Minion Name: perl-Minion -Version: 10.19 +Version: 10.20 Release: 0 Summary: Job queue License: Artistic-2.0 @@ -28,8 +28,10 @@ BuildArch: noarch BuildRequires: perl BuildRequires: perl-macros -BuildRequires: perl(Mojolicious) >= 8.50 -Requires: perl(Mojolicious) >= 8.50 +BuildRequires: perl(Mojolicious) >= 9.0 +BuildRequires: perl(YAML::XS) +Requires: perl(Mojolicious) >= 9.0 +Requires: perl(YAML::XS) %{perl_requires} %description @@ -47,6 +49,8 @@ filtering, HTTP downloads, building tarballs, warming caches and basically everything else you can imagine that's not super fast. +Take a look at our excellent documentation in Minion::Guide! + %prep %autosetup -n %{cpan_name}-%{version} find . -type f ! -path "*/t/*" ! -name "*.pl" ! -path "*/bin/*" ! -path "*/script/*" ! -name "configure" -print0 | xargs -0 chmod 644 ++++++ Minion-10.19.tar.gz -> Minion-10.20.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.19/Changes new/Minion-10.20/Changes --- old/Minion-10.19/Changes 2021-03-10 17:40:45.000000000 +0100 +++ new/Minion-10.20/Changes 2021-03-14 16:33:41.000000000 +0100 @@ -1,4 +1,9 @@ +10.20 2021-03-13 + - Removed experimental status from expiring jobs feature. + - Added Minion::Guide. + - Improved admin ui and job command to use YAML::XS to make job information easier to read. + 10.19 2021-03-10 - Improved admin ui to include search feature on all pages. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.19/MANIFEST new/Minion-10.20/MANIFEST --- old/Minion-10.19/MANIFEST 2021-03-10 21:01:56.000000000 +0100 +++ new/Minion-10.20/MANIFEST 2021-03-14 21:47:06.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/Guide.pod lib/Minion/Iterator.pm lib/Minion/Job.pm lib/Minion/Worker.pm @@ -34,6 +35,7 @@ lib/Mojolicious/Plugin/Minion/resources/public/minion/logo-black-2x.png lib/Mojolicious/Plugin/Minion/resources/public/minion/logo-black.png lib/Mojolicious/Plugin/Minion/resources/public/minion/moment/moment.js +lib/Mojolicious/Plugin/Minion/resources/public/minion/pinstripe-light.png lib/Mojolicious/Plugin/Minion/resources/public/minion/popper/popper.js lib/Mojolicious/Plugin/Minion/resources/public/minion/webfonts/fa-brands-400.eot lib/Mojolicious/Plugin/Minion/resources/public/minion/webfonts/fa-brands-400.svg diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.19/META.json new/Minion-10.20/META.json --- old/Minion-10.19/META.json 2021-03-10 21:01:56.000000000 +0100 +++ new/Minion-10.20/META.json 2021-03-14 21:47:06.000000000 +0100 @@ -33,7 +33,8 @@ }, "runtime" : { "requires" : { - "Mojolicious" : "8.50", + "Mojolicious" : "9.0", + "YAML::XS" : "0", "perl" : "5.016" } } @@ -57,6 +58,6 @@ "web" : "https://webchat.freenode.net/#mojo" } }, - "version" : "10.19", + "version" : "10.20", "x_serialization_backend" : "JSON::PP version 4.06" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.19/META.yml new/Minion-10.20/META.yml --- old/Minion-10.19/META.yml 2021-03-10 21:01:56.000000000 +0100 +++ new/Minion-10.20/META.yml 2021-03-14 21:47:05.000000000 +0100 @@ -19,7 +19,8 @@ - inc - t requires: - Mojolicious: '8.50' + Mojolicious: '9.0' + YAML::XS: '0' perl: '5.016' resources: IRC: @@ -29,5 +30,5 @@ homepage: https://mojolicious.org license: http://www.opensource.org/licenses/artistic-license-2.0 repository: https://github.com/mojolicious/minion.git -version: '10.19' +version: '10.20' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.19/Makefile.PL new/Minion-10.20/Makefile.PL --- old/Minion-10.19/Makefile.PL 2021-03-10 00:22:08.000000000 +0100 +++ new/Minion-10.20/Makefile.PL 2021-03-14 16:46:31.000000000 +0100 @@ -28,6 +28,6 @@ x_IRC => {url => 'irc://chat.freenode.net/#mojo', web => 'https://webchat.freenode.net/#mojo'} }, }, - PREREQ_PM => {Mojolicious => '8.50'}, + PREREQ_PM => {Mojolicious => '9.0', 'YAML::XS' => 0}, test => {TESTS => 't/*.t t/*/*.t'} ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.19/README.md new/Minion-10.20/README.md --- old/Minion-10.19/README.md 2021-03-05 17:35:43.000000000 +0100 +++ new/Minion-10.20/README.md 2021-03-14 16:16:27.000000000 +0100 @@ -47,5 +47,4 @@ ## Want to know more? - Take a look at our excellent - [documentation](https://mojolicious.org/perldoc/Minion)! + Take a look at our excellent [documentation](https://mojolicious.org/perldoc/Minion/Guide)! diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.19/lib/Minion/Backend/Pg.pm new/Minion-10.20/lib/Minion/Backend/Pg.pm --- old/Minion-10.19/lib/Minion/Backend/Pg.pm 2021-03-09 16:31:39.000000000 +0100 +++ new/Minion-10.20/lib/Minion/Backend/Pg.pm 2021-03-14 16:16:27.000000000 +0100 @@ -426,8 +426,7 @@ expire => 300 -Job is valid for this many seconds (from now) before it expires. Note that this option is B<EXPERIMENTAL> and might -change without warning! +Job is valid for this many seconds (from now) before it expires. =item lax @@ -940,8 +939,7 @@ expire => 300 -Job is valid for this many seconds (from now) before it expires. Note that this option is B<EXPERIMENTAL> and might -change without warning! +Job is valid for this many seconds (from now) before it expires. =item lax @@ -1056,6 +1054,6 @@ =head1 SEE ALSO -L<Minion>, L<https://minion.pm>, L<Mojolicious::Guides>, L<https://mojolicious.org>. +L<Minion>, L<Minion::Guide>, L<https://minion.pm>, L<Mojolicious::Guides>, L<https://mojolicious.org>. =cut diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.19/lib/Minion/Backend.pm new/Minion-10.20/lib/Minion/Backend.pm --- old/Minion-10.19/lib/Minion/Backend.pm 2021-03-09 16:32:32.000000000 +0100 +++ new/Minion-10.20/lib/Minion/Backend.pm 2021-03-14 16:16:27.000000000 +0100 @@ -192,8 +192,7 @@ expire => 300 -Job is valid for this many seconds (from now) before it expires. Note that this option is B<EXPERIMENTAL> and might -change without warning! +Job is valid for this many seconds (from now) before it expires. =item lax @@ -702,8 +701,7 @@ expire => 300 -Job is valid for this many seconds (from now) before it expires. Note that this option is B<EXPERIMENTAL> and might -change without warning! +Job is valid for this many seconds (from now) before it expires. =item lax @@ -819,6 +817,6 @@ =head1 SEE ALSO -L<Minion>, L<https://minion.pm>, L<Mojolicious::Guides>, L<https://mojolicious.org>. +L<Minion>, L<Minion::Guide>, L<https://minion.pm>, L<Mojolicious::Guides>, L<https://mojolicious.org>. =cut diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.19/lib/Minion/Command/minion/job.pm new/Minion-10.20/lib/Minion/Command/minion/job.pm --- old/Minion-10.19/lib/Minion/Command/minion/job.pm 2021-03-06 03:20:26.000000000 +0100 +++ new/Minion-10.20/lib/Minion/Command/minion/job.pm 2021-03-14 16:33:41.000000000 +0100 @@ -2,7 +2,7 @@ use Mojo::Base 'Mojolicious::Command'; use Mojo::JSON qw(decode_json); -use Mojo::Util qw(dumper getopt tablify); +use Mojo::Util qw(getopt tablify); has description => 'Manage Minion jobs'; has usage => sub { shift->extract_usage }; @@ -50,7 +50,7 @@ return $self->_stats if $stats; # Show history - return print dumper $minion->history if $history; + return print Minion::_dump($minion->history) if $history; # List tasks return print tablify [map { [$_, $minion->class_for_task($_)] } keys %{$minion->tasks}] if $tasks; @@ -81,7 +81,7 @@ return $minion->foreground($id) || die "Job is not ready.\n" if $foreground; # Job info - print dumper Minion::_datetime($job->info); + print Minion::_dump(Minion::_datetime($job->info)); } sub _list_jobs { @@ -101,12 +101,12 @@ print tablify \@workers; } -sub _stats { print dumper shift->app->minion->stats } +sub _stats { print Minion::_dump(shift->app->minion->stats) } sub _worker { my $worker = shift->app->minion->backend->list_workers(0, 1, {ids => [shift]})->{workers}[0]; die "Worker does not exist.\n" unless $worker; - print dumper Minion::_datetime($worker); + print Minion::_dump(Minion::_datetime($worker)); } 1; @@ -224,6 +224,6 @@ =head1 SEE ALSO -L<Minion>, L<https://minion.pm>, L<Mojolicious::Guides>, L<https://mojolicious.org>. +L<Minion>, L<Minion::Guide>, L<https://minion.pm>, L<Mojolicious::Guides>, L<https://mojolicious.org>. =cut diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.19/lib/Minion/Command/minion/worker.pm new/Minion-10.20/lib/Minion/Command/minion/worker.pm --- old/Minion-10.19/lib/Minion/Command/minion/worker.pm 2021-03-05 18:00:20.000000000 +0100 +++ new/Minion-10.20/lib/Minion/Command/minion/worker.pm 2021-03-14 16:16:27.000000000 +0100 @@ -172,6 +172,6 @@ =head1 SEE ALSO -L<Minion>, L<https://minion.pm>, L<Mojolicious::Guides>, L<https://mojolicious.org>. +L<Minion>, L<Minion::Guide>, L<https://minion.pm>, L<Mojolicious::Guides>, L<https://mojolicious.org>. =cut diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.19/lib/Minion/Command/minion.pm new/Minion-10.20/lib/Minion/Command/minion.pm --- old/Minion-10.19/lib/Minion/Command/minion.pm 2021-01-17 15:58:56.000000000 +0100 +++ new/Minion-10.20/lib/Minion/Command/minion.pm 2021-03-14 16:16:27.000000000 +0100 @@ -72,6 +72,6 @@ =head1 SEE ALSO -L<Minion>, L<https://minion.pm>, L<Mojolicious::Guides>, L<https://mojolicious.org>. +L<Minion>, L<Minion::Guide>, L<https://minion.pm>, L<Mojolicious::Guides>, L<https://mojolicious.org>. =cut diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.19/lib/Minion/Guide.pod new/Minion-10.20/lib/Minion/Guide.pod --- old/Minion-10.19/lib/Minion/Guide.pod 1970-01-01 01:00:00.000000000 +0100 +++ new/Minion-10.20/lib/Minion/Guide.pod 2021-03-14 16:16:27.000000000 +0100 @@ -0,0 +1,332 @@ + +=encoding utf8 + +=head1 NAME + +Minion::Guide - An introducion to Minion + +=head1 OVERVIEW + +This document contains an introduction to L<Minion> and explains the most important features it has to offer. + +=head1 INTRODUCTION + +Essentials every L<Minion> developer should know. + +=head2 Job queue + +Job queues allow you to process time and/or computationally intensive tasks in background processes, outside of the +request/response lifecycle of web applications. Among those tasks you'll commonly find image resizing, spam filtering, +HTTP downloads, building tarballs, warming caches and basically everything else you can imagine that's not super fast. + + Mojo::Server::Prefork +--------------+ Minion::Worker + |- Mojo::Server::Daemon [1] enqueue job -> | | -> dequeue job |- Minion::Job [1] + |- Mojo::Server::Daemon [2] | PostgreSQL | |- Minion::Job [2] + |- Mojo::Server::Daemon [3] retrieve result <- | | <- store result |- Minion::Job [3] + +- Mojo::Server::Daemon [4] +--------------+ |- Minion::Job [4] + +- Minion::Job [5] + +They are not to be confused with time based job schedulers, such as cron or systemd timers. Both serve very different +purposes, and cron jobs are in fact commonly used to enqueue L<Minion> jobs that need to follow a schedule. For example +to perform regular maintenance tasks. + +=head2 Mojolicous + +You can use L<Minion> as a standalone job queue or integrate it into L<Mojolicious> applications with the plugin +L<Mojolicious::Plugin::Minion>. + + use Mojolicious::Lite -signatures; + + plugin Minion => {Pg => 'postgresql://sri:s3cret@localhost/test'}; + + # Slow task + app->minion->add_task(poke_mojo => sub ($job, @args) { + $job->app->ua->get('mojolicious.org'); + $job->app->log->debug('We have poked mojolicious.org for a visitor'); + }); + + # Perform job in a background worker process + get '/' => sub ($c) { + $c->minion->enqueue('poke_mojo'); + $c->render(text => 'We will poke mojolicious.org for you soon.'); + }; + + app->start; + +Background worker processes are usually started with the command L<Minion::Command::minion::worker>, which becomes +automatically available when an application loads L<Mojolicious::Plugin::Minion>. + + $ ./myapp.pl minion worker + +The worker process will fork a new process for every job that is being processed. This allows for resources such as +memory to be returned to the operating system once a job is finished. Perl fork is very fast, so don't worry about the +overhead. + + Minion::Worker + |- Minion::Job [1] + |- Minion::Job [2] + +- ... + +By default up to four jobs will be processed in parallel, but that can be changed with configuration options or on +demand with signals. + + $ ./myapp.pl minion worker -j 12 + +Jobs can be managed right from the command line with L<Minion::Command::minion::job>. + + $ ./myapp.pl minion job + +You can also add an admin ui to your application by loading the plugin L<Mojolicious::Plugin::Minion::Admin>. Just make +sure to secure access before making your application publically accessible. + + # Make admin ui available under "/minion" + plugin 'Minion::Admin'; + +=head2 Deployment + +To manage background worker processes with systemd, you can use a unit configuration file like this. + + [Unit] + Description=My Mojolicious application workers + After=postgresql.service + + [Service] + Type=simple + ExecStart=/home/sri/myapp/myapp.pl minion worker -m production + KillMode=process + + [Install] + WantedBy=multi-user.target + +=head2 Consistency + +Every new job starts out as C<incative>, then progresses to C<active> when it is dequeued by a worker, and finally ends +up as C<finished> or C<failed>, depending on its result. Every C<failed> job can then be retried to progress back to the +C<inactive> state and start all over again. + + +----------+ + | | + +-----> | finished | + +----------+ +--------+ | | | + | | | | | +----------+ + | inactive | -------> | active | ------+ + | | | | | +----------+ + +----------+ +--------+ | | | + +-----> | failed | -----+ + ^ | | | + | +----------+ | + | | + +----------------------------------------------------------------+ + +The system is eventually consistent and will preserve job results for as long as you like, depending on +L<Minion/"remove_after">. But be aware that C<failed> results are presrved indefinitely, and need to be manually removed +by an administrator if they are out of automatic retries. + +While individual workers can fail in the middle of processing a job, the system will detect this and ensure that no job +is left in an uncertain state, depending on L<Minion/"missing_after">. Jobs that do not get processed after a certain +amount of time, depending on L<Minion/"stuck_after">, will be considered stuck and fail automatically. So an admin can +take a look and resolve the issue. + +=head1 FEATURES + +L<Minion> has many great features. This section is still very incomplete, but will be expanded over time. + +=head2 Priorities + +Every job enqueued with L<"enqueue" in Minion|Minion/"enqueue1"> has a priority. Jobs with a higher priority get +performed first, the default priority is C<0>. Priorities can be positive or negative, but should be in the range +between C<100> and C<-100>. + + # Default priority + $minion->enqueue('check_links', ['https://mojolicious.org']); + + # High priority + $minion->enqueue('check_links', ['https://mojolicious.org'], {priority => 30}); + + # Low priority + $minion->enqueue('check_links', ['https://mojolicious.org'], {priority => -30}); + +You can use L<Minion::Job/"retry"> to raise or lower the priority of a job. + + $job->retry({priority => 50}); + +=head2 Job results + +The result of a job has two parts. First there is its state, which can be C<finished> for a successfully processed job, +and C<failed> for the opposite. And second there's a C<result> data structure, that may be C<undef>, a scalar, a hash +reference, or an array reference. You can check both at any time in the life cycle of a job with L<Minion/"job">, all +you need is the job id. + + # Check job state + my $state = $minion->job($job_id)->info->{state}; + + # Get job result + my $result = $minion->job($job_id)->info->{result}; + +While the C<state> will be assigned automatically by L<Minion>, the C<result> for C<finished> jobs is usually assigned +manually with L<"finish" in Minion::Job|Minion::Job/"finish1">. + + $minion->add_job(job_with_result => sub ($job) { + sleep 5; + $job->finish({message => 'This job should have taken about 5 seconds'}); + }); + +For jobs that C<failed> due to an exception, that exception will be assigned as C<result>. + + $minion->add_job(job_that_fails => sub ($job) { + sleep 5; + die 'This job should always fail after 5 seconds'; + }); + +But jobs can also fail manually with L<Minion::Job/"fail">. + + $minion->add_job(job_that_fails_with_result => sub ($job) { + sleep 5; + $job->fail({errors => ['This job should fail after 5 seconds']}); + }); + +Retrieving job results is of course completely optional, and it is very common to have jobs where the result is +unimportant. + +=head2 Job progress + +Progress information and other job metadata can be stored in notes at any time during the life cycle of a job with +L<Minion::Job/"note">. The metadata can be arbitrary data strucutres constructed with scalars, hash references and array +references. + + $minion->add_job(job_with_progress => sub ($job) { + sleep 1; + $job->note(progress => '25%'); + sleep 1; + $job->note(progress => '50%'); + sleep 1; + $job->note(progress => '75%'); + sleep 1; + $job->note(progress => '100%'); + }); + +Notes, similar to job results, can be retrieved with L<Minion/"job">, all you need is the job id. + + # Get job metadata + my $progress = $minion->job($job_id)->info->{notes}{progress}; + +You can also use notes to store arbitrary metadata with new jobs when you create them with +L<"enqueue" in Minion|Minion/"enqueue1">. + + # Create job with metadata + $minion->enqueue('job_with_progress', [], {notes => {progress => 0, something_else => [1, 2, 3]}}); + +The admin ui provided by L<Mojolicious::Plugin::Minion::Admin> allows searching for jobs containing a certain note, so +you can also use them to tag jobs. + +=head2 Delayed jobs + +The C<delay> option of L<"enqueue" in Minion|Minion/"enqueue1"> can be used to delay the processing of a job by a +certain amount of seconds (from now). + + # Job will not be processed for 60 seconds + $minion->enqueue('check_links', ['https://mojolicious.org'], {delay => 20}); + +You can use L<Minion::Job/"retry"> to change the delay. + + $job->retry({delay => 10}); + +=head2 Expiring jobs + +The C<expire> option of L<"enqueue" in Minion|Minion/"enqueue1"> can be used to limit for how many seconds (from now) a +job should be valid before it expires and gets deleted from the queue. + + # Job will vanish if it is not dequeued within 60 seconds + $minion->enqueue('check_links', ['https://mojolicious.org'], {expire => 60}); + +You can use L<Minion::Job/"retry"> to reset the expiration time. + + $job->retry({expire => 30}); + +=head2 Custom workers + +In cases where you don't want to use L<Minion> together with L<Mojolicious>, you can just skip the plugins and write +your own worker scripts. + + #!/usr/bin/perl + use strict; + use warnings; + + use Minion; + + # Connect to backend + my $minion = Minion->new(Pg => 'postgresql://postgres@/test'); + + # Add tasks + $minion->add_task(something_slow => sub ($job, @args) { + sleep 5; + say 'This is a background worker process.'; + }); + + # Start a worker to perform up to 12 jobs concurrently + my $worker = $minion->worker; + $worker->status->{jobs} = 12; + $worker->run; + +The method L<Minion::Worker/"run"> contains all features you would expect from a L<Minion> worker and can be easily +configured with L<Minion::Worker/"status">. For even more customization options L<Minion::Worker> also has a very rich +low level API you could for example use to build workers that do not fork at all. + +=head2 Task plugins + +As your L<Mojolicious> application grows, you can move tasks into application specific plugins. + + package MyApp::Task::PokeMojo; + use Mojo::Base 'Mojolicious::Plugin', -signatures; + + sub register ($self, $app, $config) { + $app->minion->add_task(poke_mojo => sub ($job, @args) { + $job->app->ua->get('mojolicious.org'); + $job->app->log->debug('We have poked mojolicious.org for a visitor'); + }); + } + + 1; + +Which are loaded like any other plugin from your application. + + # Mojolicious + $app->plugin('MyApp::Task::PokeMojo'); + + # Mojolicious::Lite + plugin 'MyApp::Task::PokeMojo'; + +=head2 Task classes + +For more flexibility, or if you are using L<Minion> as a standalone job queue, you can also move tasks into dedicated +classes. Allowing the use of Perl features such as inheritance and roles. But be aware that support for task classes is +still B<EXPERIMENTAL> and might change without warning! + + package MyApp::Task::PokeMojo; + use Mojo::Base 'Minion::Job', -signatures; + + sub run ($self, @args) { + $self->app->ua->get('mojolicious.org'); + $self->app->log->debug('We have poked mojolicious.org for a visitor'); + } + + 1; + +Task classes are registered just like any other task with L<Minion/"add_task"> and you can even register the same class +with multiple names. + + $minion->add_task(poke_mojo => 'MyApp::Task::PokeMojo'); + +=head1 MORE + +You can continue with L<Mojolicious::Guides> now or take a look at the L<Mojolicious +wiki|https://github.com/mojolicious/mojo/wiki>, which contains a lot more documentation and examples by many different +authors. + +=head1 SUPPORT + +If you have any questions the documentation might not yet answer, don't hesitate to ask in the +L<Forum|https://forum.mojolicious.org> or the official IRC channel C<#mojo> on C<chat.freenode.net> +(L<chat now!|https://webchat.freenode.net/#mojo>). + +=cut diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.19/lib/Minion/Iterator.pm new/Minion-10.20/lib/Minion/Iterator.pm --- old/Minion-10.19/lib/Minion/Iterator.pm 2021-03-06 03:00:38.000000000 +0100 +++ new/Minion-10.20/lib/Minion/Iterator.pm 2021-03-14 16:16:27.000000000 +0100 @@ -100,6 +100,6 @@ =head1 SEE ALSO -L<Minion>, L<https://minion.pm>, L<Mojolicious::Guides>, L<https://mojolicious.org>. +L<Minion>, L<Minion::Guide>, L<https://minion.pm>, L<Mojolicious::Guides>, L<https://mojolicious.org>. =cut diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.19/lib/Minion/Job.pm new/Minion-10.20/lib/Minion/Job.pm --- old/Minion-10.19/lib/Minion/Job.pm 2021-01-17 15:58:55.000000000 +0100 +++ new/Minion-10.20/lib/Minion/Job.pm 2021-03-14 16:16:27.000000000 +0100 @@ -520,8 +520,7 @@ expire => 300 -Job is valid for this many seconds (from now) before it expires. Note that this option is B<EXPERIMENTAL> and might -change without warning! +Job is valid for this many seconds (from now) before it expires. =item lax @@ -579,6 +578,6 @@ =head1 SEE ALSO -L<Minion>, L<https://minion.pm>, L<Mojolicious::Guides>, L<https://mojolicious.org>. +L<Minion>, L<Minion::Guide>, L<https://minion.pm>, L<Mojolicious::Guides>, L<https://mojolicious.org>. =cut diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.19/lib/Minion/Worker.pm new/Minion-10.20/lib/Minion/Worker.pm --- old/Minion-10.19/lib/Minion/Worker.pm 2021-03-05 18:00:07.000000000 +0100 +++ new/Minion-10.20/lib/Minion/Worker.pm 2021-03-14 16:16:27.000000000 +0100 @@ -373,6 +373,11 @@ Run worker and wait for L</"WORKER SIGNALS">. + # Start a worker for a special named queue + my $worker = $minion->worker; + $worker->status->{queues} = ['important']; + $worker->run; + These L</"status"> options are currently available: =over 2 @@ -467,6 +472,6 @@ =head1 SEE ALSO -L<Minion>, L<https://minion.pm>, L<Mojolicious::Guides>, L<https://mojolicious.org>. +L<Minion>, L<Minion::Guide>, L<https://minion.pm>, L<Mojolicious::Guides>, L<https://mojolicious.org>. =cut diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.19/lib/Minion.pm new/Minion-10.20/lib/Minion.pm --- old/Minion-10.19/lib/Minion.pm 2021-03-10 18:49:05.000000000 +0100 +++ new/Minion-10.20/lib/Minion.pm 2021-03-14 16:33:41.000000000 +0100 @@ -12,6 +12,7 @@ use Mojo::Promise; use Mojo::Server; use Mojo::Util qw(scope_guard steady_time); +use YAML::XS qw(Dump); has app => sub { $_[0]{app_ref} = Mojo::Server->new->build_app('Mojo::HelloWorld') }, weak => 1; has 'backend'; @@ -20,7 +21,7 @@ has [qw(remove_after stuck_after)] => 172800; has tasks => sub { {} }; -our $VERSION = '10.19'; +our $VERSION = '10.20'; sub add_task { my ($self, $name, $task) = @_; @@ -157,6 +158,8 @@ return $self; } +sub _dump { local $YAML::XS::Boolean = 'JSON::PP'; Dump(@_) } + sub _iterator { my ($self, $jobs, $options) = (shift, shift, shift // {}); return Minion::Iterator->new(minion => $self, options => $options, jobs => $jobs); @@ -226,121 +229,7 @@ request/response lifecycle of web applications. Among those tasks you'll commonly find image resizing, spam filtering, HTTP downloads, building tarballs, warming caches and basically everything else you can imagine that's not super fast. -=head1 BASICS - -You can use L<Minion> as a standalone job queue or integrate it into L<Mojolicious> applications with the plugin -L<Mojolicious::Plugin::Minion>. - - use Mojolicious::Lite -signatures; - - plugin Minion => {Pg => 'postgresql://sri:s3cret@localhost/test'}; - - # Slow task - app->minion->add_task(poke_mojo => sub ($job, @args) { - $job->app->ua->get('mojolicious.org'); - $job->app->log->debug('We have poked mojolicious.org for a visitor'); - }); - - # Perform job in a background worker process - get '/' => sub ($c) { - $c->minion->enqueue('poke_mojo'); - $c->render(text => 'We will poke mojolicious.org for you soon.'); - }; - - app->start; - -Background worker processes are usually started with the command L<Minion::Command::minion::worker>, which becomes -automatically available when an application loads L<Mojolicious::Plugin::Minion>. - - $ ./myapp.pl minion worker - -The worker process will fork a new process for every job that is being processed. This allows for resources such as -memory to be returned to the operating system once a job is finished. Perl fork is very fast, so don't worry about the -overhead. - - Minion::Worker - |- Minion::Job [1] - |- Minion::Job [2] - +- ... - -By default up to four jobs will be processed in parallel, but that can be changed with configuration options or on -demand with signals. - - $ ./myapp.pl minion worker -j 12 - -Jobs can be managed right from the command line with L<Minion::Command::minion::job>. - - $ ./myapp.pl minion job - -You can also add an admin ui to your application by loading the plugin L<Mojolicious::Plugin::Minion::Admin>. Just make -sure to secure access before making your application publically accessible. - - # Make admin ui available under "/minion" - plugin 'Minion::Admin'; - -To manage background worker processes with systemd, you can use a unit configuration file like this. - - [Unit] - Description=My Mojolicious application workers - After=postgresql.service - - [Service] - Type=simple - ExecStart=/home/sri/myapp/myapp.pl minion worker -m production - KillMode=process - - [Install] - WantedBy=multi-user.target - -Every job can fail or succeed, but not get lost, the system is eventually consistent and will preserve job results for -as long as you like, depending on L</"remove_after">. While individual workers can fail in the middle of processing a -job, the system will detect this and ensure that no job is left in an uncertain state, depending on -L</"missing_after">. - -=head1 GROWING - -And as your application grows, you can move tasks into application specific plugins. - - package MyApp::Task::PokeMojo; - use Mojo::Base 'Mojolicious::Plugin', -signatures; - - sub register ($self, $app, $config) { - $app->minion->add_task(poke_mojo => sub ($job, @args) { - $job->app->ua->get('mojolicious.org'); - $job->app->log->debug('We have poked mojolicious.org for a visitor'); - }); - } - - 1; - -Which are loaded like any other plugin from your application. - - # Mojolicious - $app->plugin('MyApp::Task::PokeMojo'); - - # Mojolicious::Lite - plugin 'MyApp::Task::PokeMojo'; - -=head1 TASK CLASSES - -For even more flexibility you can also move tasks into dedicated classes. Allowing the use of Perl features such as -inheritance and roles. But be aware that support for task classes is still B<EXPERIMENTAL> and might change without -warning! - - package MyApp::Task::PokeMojo; - use Mojo::Base 'Minion::Job', -signatures; - - sub run ($self, @args) { - $self->app->ua->get('mojolicious.org'); - $self->app->log->debug('We have poked mojolicious.org for a visitor'); - } - - 1; - -Task classes are registered just like any other task with L</"add_task"> and you can even register the same class with -multiple names. - - $minion->add_task(poke_mojo => 'MyApp::Task::PokeMojo'); +Take a look at our excellent documentation in L<Minion::Guide>! =head1 EXAMPLES @@ -511,8 +400,7 @@ expire => 300 -Job is valid for this many seconds (from now) before it expires. Note that this option is B<EXPERIMENTAL> and might -change without warning! +Job is valid for this many seconds (from now) before it expires. =item lax @@ -614,7 +502,7 @@ my $state = $minion->job($id)->info->{state}; # Get job metadata - my $progress = $minion->$job($id)->info->{notes}{progress}; + my $progress = $minion->job($id)->info->{notes}{progress}; # Get job result my $result = $minion->job($id)->info->{result}; @@ -1226,11 +1114,13 @@ Licensed under the MIT License, L<http://creativecommons.org/licenses/MIT>. -=head1 AUTHOR +=head1 AUTHORS + +=head2 Project Founder Sebastian Riedel, C<s...@cpan.org>. -=head1 CREDITS +=head2 Contributors In alphabetical order: @@ -1263,6 +1153,7 @@ =head1 SEE ALSO -L<https://github.com/mojolicious/minion>, L<https://minion.pm>, L<Mojolicious::Guides>, L<https://mojolicious.org>. +L<https://github.com/mojolicious/minion>, L<Minion::Guide>, L<https://minion.pm>, L<Mojolicious::Guides>, +L<https://mojolicious.org>. =cut diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.19/lib/Mojolicious/Plugin/Minion/Admin.pm new/Minion-10.20/lib/Mojolicious/Plugin/Minion/Admin.pm --- old/Minion-10.19/lib/Mojolicious/Plugin/Minion/Admin.pm 2021-03-09 23:07:22.000000000 +0100 +++ new/Minion-10.20/lib/Mojolicious/Plugin/Minion/Admin.pm 2021-03-14 16:16:27.000000000 +0100 @@ -217,6 +217,6 @@ =head1 SEE ALSO -L<Minion>, L<https://minion.pm>, L<Mojolicious::Guides>, L<https://mojolicious.org>. +L<Minion>, L<Minion::Guide>, L<https://minion.pm>, L<Mojolicious::Guides>, L<https://mojolicious.org>. =cut diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.19/lib/Mojolicious/Plugin/Minion/resources/public/minion/app.css new/Minion-10.20/lib/Mojolicious/Plugin/Minion/resources/public/minion/app.css --- old/Minion-10.19/lib/Mojolicious/Plugin/Minion/resources/public/minion/app.css 2021-03-10 18:43:22.000000000 +0100 +++ new/Minion-10.20/lib/Mojolicious/Plugin/Minion/resources/public/minion/app.css 2021-03-14 16:16:27.000000000 +0100 @@ -1,3 +1,6 @@ +html { + height: 100%; +} div.stats { border: solid 1px #777; border-radius: 4px; @@ -43,6 +46,27 @@ .hiddenRow { padding: 0 !important; } +.mojo-copy { + font-size: 12px; +} +.mojo-copy, .mojo-copy a { + color: #777; +} +.mojo-footer { + background: url(../minion/pinstripe-light.png); + background-color: #f2ece9; + box-shadow: inset 0 10px 10px -5px #ddd; + color: #666; +} +.mojo-footer a:hover { + color: #000; + text-decoration: none; +} +.mojo-social a { + color: #666; + font-size: 1.5em; + padding: 0.2em; +} .table thead tr th { border-top: 0 !important; } Binary files old/Minion-10.19/lib/Mojolicious/Plugin/Minion/resources/public/minion/pinstripe-light.png and new/Minion-10.20/lib/Mojolicious/Plugin/Minion/resources/public/minion/pinstripe-light.png differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.19/lib/Mojolicious/Plugin/Minion/resources/templates/layouts/minion.html.ep new/Minion-10.20/lib/Mojolicious/Plugin/Minion/resources/templates/layouts/minion.html.ep --- old/Minion-10.19/lib/Mojolicious/Plugin/Minion/resources/templates/layouts/minion.html.ep 2021-03-10 18:44:42.000000000 +0100 +++ new/Minion-10.20/lib/Mojolicious/Plugin/Minion/resources/templates/layouts/minion.html.ep 2021-03-14 16:16:27.000000000 +0100 @@ -22,7 +22,7 @@ </script> %= content_for 'head' </head> - <body> + <body class="d-flex flex-column h-100"> <nav class="navbar navbar-expand-lg navbar-light bg-light mb-3 border-bottom"> <div class="container"> %= link_to 'minion_dashboard' => (class => 'navbar-brand') => begin @@ -83,7 +83,7 @@ </div> </div> </nav> - <div class="container"> + <div class="container flex-grow-1"> <div class="modal fade" id="searchModal" tabindex="-1" role="dialog" aria-labelledby="searchModalLabel" aria-hidden="true"> <div class="modal-dialog" role="document"> @@ -134,5 +134,25 @@ </div> %= content </div> + <footer> + <div class="container-fluid p-3 mojo-footer"> + <div class="container"> + <div class="row"> + <div class="col-sm align-self-center text-center"> + <b>Free</b> and <b>Open Source</b>. + </div> + <div class="col-sm align-self-center text-center mojo-copy"> + <i class="far fa-copyright"></i> 2014-2021 Sebastian Riedel and the + <a href="https://docs.mojolicious.org/Minion#AUTHORS">Minion contributors</a>. + </div> + <div class="col-sm align-self-center text-center mojo-social"> + <a alt="GitHub" href="https://github.com/mojolicious/minion"><i class="fab fa-github-alt"></i></a> + <a alt="Twitter" href="https://twitter.com/perlmojo"><i class="fab fa-twitter"></i></a> + <a alt="LinkedIn" href="https://www.linkedin.com/groups/8963713/"><i class="fab fa-linkedin"></i></a> + </div> + </div> + </div> + </div> + </footer> </body> </html> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.19/lib/Mojolicious/Plugin/Minion/resources/templates/minion/jobs.html.ep new/Minion-10.20/lib/Mojolicious/Plugin/Minion/resources/templates/minion/jobs.html.ep --- old/Minion-10.19/lib/Mojolicious/Plugin/Minion/resources/templates/minion/jobs.html.ep 2021-03-10 20:57:02.000000000 +0100 +++ new/Minion-10.20/lib/Mojolicious/Plugin/Minion/resources/templates/minion/jobs.html.ep 2021-03-14 16:33:41.000000000 +0100 @@ -155,7 +155,7 @@ <tr> <td colspan="9" class="hiddenRow"> <div class="collapse" id="job<%= $i %>"> - <pre class="border rounded"><%= dumper Minion::_datetime $job %></pre> + <pre class="border rounded"><%= Minion::_dump(Minion::_datetime($job)) %></pre> </div> </td> </tr> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.19/lib/Mojolicious/Plugin/Minion/resources/templates/minion/workers.html.ep new/Minion-10.20/lib/Mojolicious/Plugin/Minion/resources/templates/minion/workers.html.ep --- old/Minion-10.19/lib/Mojolicious/Plugin/Minion/resources/templates/minion/workers.html.ep 2020-08-01 00:57:23.000000000 +0200 +++ new/Minion-10.20/lib/Mojolicious/Plugin/Minion/resources/templates/minion/workers.html.ep 2021-03-14 16:33:41.000000000 +0100 @@ -73,7 +73,7 @@ <tr> <td colspan="7" class="hiddenRow"> <div class="collapse" id="worker<%= $i %>"> - <pre class="border rounded"><%= dumper Minion::_datetime $worker %></pre> + <pre class="border rounded"><%= Minion::_dump(Minion::_datetime($worker)) %></pre> </div> </td> </tr> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Minion-10.19/lib/Mojolicious/Plugin/Minion.pm new/Minion-10.20/lib/Mojolicious/Plugin/Minion.pm --- old/Minion-10.19/lib/Mojolicious/Plugin/Minion.pm 2021-01-17 15:58:57.000000000 +0100 +++ new/Minion-10.20/lib/Mojolicious/Plugin/Minion.pm 2021-03-14 16:16:27.000000000 +0100 @@ -77,6 +77,6 @@ =head1 SEE ALSO -L<Minion>, L<https://minion.pm>, L<Mojolicious::Guides>, L<https://mojolicious.org>. +L<Minion>, L<Minion::Guide>, L<https://minion.pm>, L<Mojolicious::Guides>, L<https://mojolicious.org>. =cut