Для работы с сервером gearmand помимо модулей на перле удобно воспользоваться и XS-вариантами Gearman::XS.
На спане есть модули для всех трех частей рабочей среды — серверов, воркеров и клиентов — однако в реальности скорее всего не возникнет необходимости в модуле Gearman::XS::Server, работающего сервером; достаточно воспользоваться XS-переходниками для воркера (Gearman::XS::Worker) и клиента (Gearman::XS::Client).
Создать и воркер, и клиент почти также просто, как и их pure-Perl-аналоги. Некоторое неудобство может вызвать C-подобный стиль обработки ошибок, который показан в самом начале документации.
Минимальный вариант воркера, экспортирующего функцию echo, которая увеличивает на единицу полученный аргумент, выглядит так:
use v5.10;
use strict;
use Gearman::XS::Worker;
my $worker = new Gearman::XS::Worker;
$worker->add_server('127.0.0.1', 4730);
$worker->add_function('echo', 0, \&echo, undef);
$worker->work() while 1;
sub echo {
my $job = shift;
return $job->workload() + 1;
}
Клиентская часть, синхронно вызывающая метод echo:
use v5.10;
use strict;
use Gearman::XS::Client;
my $client = new Gearman::XS::Client;
$client->add_server('127.0.0.1', 4730);
my ($ret, $result) = $client->do('echo', '15'); # arg as string!
say $result;
Следует обратить внимание на два момента. Во-первых, вызов возвращает две величины — код завершения $ret и собственно результат $result. Во-вторых, в качестве аргумента следует передавать именно строку, даже если (как в показанном примере) аргумент — число (иначе метод вернет 2 вместо 16).
Наконец, асинхронный вариант постановки нескольких задач:
use v5.10;
use strict;
use Gearman::XS::Client;
my $client = new Gearman::XS::Client;
$client->add_server('127.0.0.1', 4730);
my ($ret1, $task1) = $client->add_task('echo', '15');
my ($ret2, $task2) = $client->add_task('echo', '51');
$client->run_tasks();
Эта программа завершается по окончании обеих задач, но задачи можно написать так, что возвращаемый результат не нужен (а получить из переменных $task1 и $task2 после завершения задач уже ничего не получается: Segmentation fault на любую попытку взять из них данные после выполнения задачи; а может зря я в самом начале отмел Gearman::XS::Server?).
Комментировать