第十天 - Minion Stands Alone
— 焉知非鱼Minion 作业队列是一个非常有用的工具,但有时我需要将它用于非 Web 项目。那么,如何在不需要 Mojolicious Web 应用程序的情况下使用 Minion?
如果我没有足够大的工作需要 Beam::Minion 提供的任务组织,虽然 Minion 可以用作完全独立的库,但最简单的解决方案就是构建一个 Mojolicious 应用程序。幸运的是,一个 Mojolicious 应用程序可以只有2行:
use Mojolicious::Lite;
app->start;
现在,如果我从未运行过 web 守护进程,那么这绝不会是一个网站。那么,如果没有人使用网络浏览器访问它,这可以称为 Web 应用程序吗?🤔
Add Minion #
要使用 Minion,请将 Minion 插件添加到应用程序。对于这个例子,我将使用 SQLite Minion 后端,这样我就不需要运行单独的数据库进程,但如果你有一个接受远程连接的数据库,Minion 可以在多台机器上工作。
plugin Minion => {
SQLite => 'sqlite:' . app->home->child('minion.db'),
};
加载 Minion 插件后,我的应用程序获得了一些新功能:
- 我可以使用 minion.add_task 助手程序添加 Minion 任务(可运行的代码)
- 我可以通过多种方式排队工作:
- 从命令行使用 minion job 命令
- 从应用程序内部使用 minion.enqueue 助手程序
- 从任何 Perl 脚本加载 Minion 并使用 enqueue 方法
- 我可以使用 minion worker 命令运行一个 Minion worker,它将执行任何排队的作业
Create a Task #
我将创建一个名为 check_url
的任务来检查下载 URL 所需的时间。 Time::HiRes 核心模块将为我提供高分辨率时间。
#!/usr/bin/env perl
use v5.28;
use Mojolicious::Lite;
use experimental qw( signatures );
use Time::HiRes qw( time );
plugin Minion => {
SQLite => 'sqlite:' . app->home->child('minion.db'),
};
app->minion->add_task(
check_url => sub( $job, $url ) {
my $start = time;
my $tx = $job->app->ua->head( $url );
my $elapsed = time - $start;
$job->app->log->info(
sprintf 'Fetching %s took %.3f seconds', $url, $elapsed
);
# If there's an error loading the web page, fail the job
if ( $tx->error ) {
$job->app->log->error(
sprintf 'Error loading URL (%s): %s (%s)',
$url, @{ $tx->error }{qw( code message )},
);
return $job->fail(
sprintf '%s: %s', @{ $tx->error }{qw( code message )}
);
}
$job->finish( $elapsed );
},
);
app->start;
Enqueuing Jobs #
现在我有一个任务,我可以排队一些工作。我可以使用 minion job 命令添加作业:
$ perl myapp.pl minion job -e check_url -a '["http://mojolicious.org"]'
或者通过加载Minion并使用 enqueue 方法 从另一个 Perl 脚本内部:
#!/usr/bin/env perl
use Minion;
my $minion = Minion->new(
SQLite => 'sqlite:minion.db', # The same database as the worker
);
$minion->enqueue(
check_url => ['http://mojolicious.org'],
);
Running a Worker #
我已经排队了工作,但没有发生任何事情,直到我使用 minion worker 命令运行一个 worker 才会发生任何事情:
$ perl myapp.pl minion worker
一旦工人启动,它将立即开始处理我告诉它运行的工作。
就是这样!我在没有 Mojolicious Web 应用程序的情况下使用 Minion。查看 Minion 应用程序的源代码和 enqueue.pl 脚本。