Установка события «завершение» для Mojolicious / Minion ::Job

#perl #mojolicious

#perl #mojolicious

Вопрос:

Я пытаюсь, чтобы задания Minion возвращались в веб-приложение Mojolicious после завершения (возможно, путем отправки сообщения в API). Основная идея здесь заключается в том, чтобы веб-приложение возвращалось к клиенту, который загрузил / запустил задание.

Я пытался это сделать:

 get '/' => sub {
    my $c = shift;
    my $id = $c->minion->enqueue('thing', [ qw/a b 1/, { foo => 'bar' } ]);

    my $job = $c->minion->job($id);

    $job->on(finish => sub ($job) {
              my $id   = $job->id;
              my $task = $job->task;
              $job->app->log->info(qq{Job "$id" was performed with task "$task"});
         });


    $c->render(template => 'index');
};
 

что не работает — я думаю, потому, что событие генерируется только в процессе выполнения задания, и событие не сериализуется и не ставится в очередь.

Если я сделаю это:

 app->minion->add_task
    (thing => sub ($job, $c, $sub, @args) {
     $job->on(finish => sub ($job) {
              my $id   = $job->id;
              my $task = $job->task;
              $job->app->log->info(qq{Job "$id" was performed with task "$task"});
          });
          sleep 2;
     });
 

это работает нормально, но это означает, что я должен добавлять обработку событий к каждой задаче, что усложняет код.

Есть ли способ избежать этого?

Я думаю о:

  1. возможность установить класс по умолчанию для заданий (например, чтобы все задания относились к подклассу Mojo::Job Minion::Job::WithFeedback )
  2. а еще лучше, возможность вводить роли в создание задач (чтобы вы могли делать $c->minion->enqueue('thing', [ qw/a b 1/, { foo => 'bar' } ], { roles => qw/ WithFeedback WithTimeout/);

Я знаю, что мог бы регулярно опрашивать все задания и видеть, какой статус изменился — это то, что Minion::Admin делает плагин, — но я хотел бы посмотреть, есть ли другой способ, который не требует опроса базы данных.

Возможно ли это? и раз уж мы об этом заговорили — разве это плохая идея сама по себе?