第十天 - Minion Stands Alone

Minion 作业队列是一个非常有用的工具,但有时我需要将它用于非 Web 项目。那么,如何在不需要 Mojolicious Web 应用程序的情况下使用 Minion?

如果我没有足够大的工作需要 Beam::Minion 提供的任务组织,虽然 Minion 可以用作完全独立的库,但最简单的解决方案就是构建一个 Mojolicious 应用程序。幸运的是,一个 Mojolicious 应用程序可以只有2行:

1
2
use Mojolicious::Lite;
app->start;

现在,如果我从未运行过 web 守护进程,那么这绝不会是一个网站。那么,如果没有人使用网络浏览器访问它,这可以称为 Web 应用程序吗?🤔

Add Minion

要使用 Minion,请将 Minion 插件添加到应用程序。对于这个例子,我将使用 SQLite Minion 后端,这样我就不需要运行单独的数据库进程,但如果你有一个接受远程连接的数据库,Minion 可以在多台机器上工作。

1
2
3
plugin Minion => {
SQLite => 'sqlite:' . app->home->child('minion.db'),
};

加载 Minion 插件后,我的应用程序获得了一些新功能:

  • 我可以使用 minion.add_task 助手程序添加 Minion 任务(可运行的代码)
  • 我可以通过多种方式排队工作:
  • 我可以使用 minion worker 命令运行一个 Minion worker,它将执行任何排队的作业

Create a Task

我将创建一个名为 check_url 的任务来检查下载 URL 所需的时间。 Time::HiRes 核心模块将为我提供高分辨率时间。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/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 命令添加作业:

1
$ perl myapp.pl minion job -e check_url -a '["http://mojolicious.org"]'

或者通过加载Minion并使用 enqueue 方法 从另一个 Perl 脚本内部:

1
2
3
4
5
6
7
8
#!/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 才会发生任何事情:

1
$ perl myapp.pl minion worker

一旦工人启动,它将立即开始处理我告诉它运行的工作。

就是这样!我在没有 Mojolicious Web 应用程序的情况下使用 Minion。查看 Minion 应用程序的源代码和 enqueue.pl 脚本