-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Job progress #14
Comments
Нет в этом модуле прогресс выполнения заданий не предусмотрен. |
технически это реализовать можно либо на уровне самого джоба, (или базового класса джобов) class MyJob implements JoиInterface
{
private $progress;
public function execute($queue)
{
try{
$this->executeInternal();
}catch(\Throwable $e){
$this->saveProgress(..);
throw $e;
}
}
} либо поведением которое добавит свойство прогресса и будет записывать его по событиям завершения/ошибки или еще когда но главная проблема в том, что довольно проблематично добавить какие-то свои записи в таблицу текущего мониторинга - это надо перекрывать модель, свои миграции... |
Спасибо за идею!
С job-ом я пока размышляю на предмет событий. Чтоб обработку можно было добавить в сам монитор |
Даже не знаю стоит ли. Прогресс выполнения чего-либо это уже не про очередь, это частный случай. И мониторинг задумывался как отладочное расширение, которое легко включить, и так же легко выключить, если отпала необходимость. Я обычное если нужен прогресс чего-либо решаю вопрос на уровне проекта. |
В моем случае, как раз таки это и нужно для отладки.
Задачи пишут разные программисты в команде, иногда "тяжелые" задачи нужно дополнительно разбить на части и проанализировать каждую отдельно, чтоб узнать, где и по какой причине происходит задержка... (кривой запрос, долгая связь со сторонним сервисом, устаревшая библиотека... ) |
Ну само собой приходится решать на уровне проекта... но штука в том что юзкейсы довольно схожие и в конечном итоге все сводится либо к допилу этого модуля либо аналога заточенного под конкретные модели.
Ну еще иногда для детальной отладки проброска контекста джоба в параметры приложения, и соответственно настроенный DbLogTarget который добавлет этот контекст в таблицу, для быстрого отсмотра по конкретной джобе, но это уже к модулю практически не относится, только во вьюху доп.ссылка добавляется |
Я у себя стараюсь проектировать архитектуру так, чтобы лонг-ранов не было. Лонг-ран, как процесс, превращается в лонг-ран, как перечень джобов, которые нужно выполнить. Каждая итерация - отдельный джоб. Тогда и прогрессе легко отследить по соотношению того, сколько джобов выполнено и сколько осталось. Тут отсылка к еще недоработанному в виде расширения yii2-queue-chain. И перезапуск фейлов легко организовать штатными средствами очереди. Но запрос понятен. Нужно подумать что и как лучше сделать, чтобы сохранить независимость модуля и впилить обновление прогресса. |
Про лог-ран как перечень джобов - да, но при этом это все равно остается одним логическим джобом и для этого как раз и нужен общий стейт и/или завязка на объект-инициатор чтоб пробрасывать стейт туда. но бывают некоторые кейсы когда лонг-ран бить не выгодно - ставится в ночь, например билд каких-то квартальных отчетов или импорт типовых данных с внешки по апи - фигачится оно через guzzle асинхронно на итераторах, протечки практически никакой - тут как раз если бить будет сильный оверхед на инфраструктуру,промежуточные кеши, а если фиксировать курсор стейта, то при фейле продолжить дальше и всё. Но это конечно от специфики, объемов данных и важности таска зависит |
Ну да, эта идея и лежит в основе queue-chain:
Да, бывает. Но такие лонг-раны не всегда вообще имеют отношение к очередям. Могут быть обычными крон-командами. Ну и реализация прогресса опять же напрашивается на проектный уровень. |
Вот снова нарисовалось - надо при фейле таска юзеру аккуратную ошибочку вывести... куда удобнее ее было бы класть в кастомное поле лога джоба, чем вставлять еще одно поле в модель-инициатора для текста ошибки (у нас связано с моделями). |
https://github.com/zhuravljov/yii2-queue-monitor/blob/master/src/JobMonitor.php#L179 seems we can got result only for success execution. What about support special Exception type with additional result message for storing it as result for failed execution? |
@Insolita how it could be used? |
class JobException extend \Exception
{
public $result;
public function __construct(string $message, array $result, int $code=0, $previous = null)
{
$this->result = $result;
parent::__construct($message, $code, $previous);
}
}
class MyJob implements JobInterface
{
public function execute($queue)
{
try{
$this->executeInternal();
}catch(\Throwable $e){
throw new JobException($e->getMessage(), ['some advanced data for result - like current step, user-friendly error, additional context.. '], 0, $e);
}
}
} |
Если exception рассматривается как результат, то не проще ли обычным способом? class MyJob implements JobInterface
{
public function execute($queue)
{
try {
return $this->executeInternal();
} catch (\Throwable $e) {
return ['some advanced data for result - like current step, user-friendly error, additional context.. '];
}
}
} |
да но онож на retry не пойдет |
Верно, не пойдет. Я же и говорю про тот кейс, где исключение = результат. |
А стоит ли тогда создавать структурированное исключенние, если данные, которые туда будут передаваться, автоматика далее использовать не будет? class JobException extends \Exception
{
public function __construct(string $message, array $result, int $code=0, $previous = null)
{
$message .= "\n" . VarDumper::dumpAsString($result);
parent::__construct($message, $code, $previous);
}
} |
@Insolita кстати, на тему прогресса мысль пришла. Можно было бы |
Его как раз тогда можно будет залоггировать имеется в виду что вместо https://github.com/zhuravljov/yii2-queue-monitor/blob/master/src/JobMonitor.php#L164 public function afterError(ExecEvent $event)
{
$push = static::$startedPush ?: $this->getPushRecord($event);
if (!$push) {
return;
}
if ($push->isStopped()) {
// Breaks retry in case is stopped
$event->retry = false;
}
if ($push->last_exec_id) {
ExecRecord::updateAll([
'finished_at' => time(),
'memory_usage' => static::$startedPush ? memory_get_peak_usage() : null,
'error' => $event->error,
'result_data' => $event->error instanceof JobException? $event->error->result:null,
'retry' => $event->retry,
], [
'id' => $push->last_exec_id
]);
}
} А сейчас мы при ошибке в error получаем полный exception с трейсом который трудно препарировать, он норм для внтренней отладки, но его никому не покажешь |
Любопытно, но это на уровне queue надо разруливать... |
Смущает то, что
Так его и не нужно препарировать. Если стоит такая задача, в которой нужна специфическая обработка отдельных типов исключений, лучше сделать отдельный обработчик для А если протаскивать это на сторону мониторинга, то нужно проектировать плаганизацию уже самого мониторинга со своими событиями и обработчиками. Чтобы, как в водрдпрессе, через хуки можно было бы вклиниться на любом этапе: сохранение, рендеринг вьюх и прочее. |
Если бы php допускал концепцию приватных классов то по задумке за пределами неймспейса |
а если чекать исключение на предмет наличия property или метода getResultData ? Вот сейчас я наконец поняла, что ты хочешь держать его с возможностью безболезненно отключить, или только в dev/staging подключать |
Да, это ключевая идея. Что-то типа У меня есть проекты с очень плотным потоком, что проходит через очередь. И включенный в боевом режиме мониторинг сильно просаживает производительность. А нужен он только иногда, когда нужно разобраться в какой-то проблеме. |
Ну ясно.. Мои кейсы всё-таки больше с заявзкой к бизнес-логике и джобы и выкидывание модуля не рассматривается, он какбы часть проекта... которую хочется подключить, настроить и не париться. Поэтому ни фильтры по интерфейсам ни доп.методы в поведении не смущают. (а чтобы не просаживалось на ерундовые задачи - исключить ненужное настройками) |
Роман, подскажите, пожалуйста, и возможно ли, реализовать следующую логику.
Есть задача. Выполняется она длительное время (10-15 мин.).
В коде самой задачи я хочу проставить некие метки о ее готовности (прогресс исполнения). Нужно это, чтобы знать, в каком именно месте кода происходит "падение" воркера.
В yiisoft/yii2-queue/src/cli/Queue.php:113 есть такой участок кода с событием self::EVENT_WORKER_LOOP
Смогу ли я через воркер считать значение $progress задачи и записать его в монитор.
И как именно?
Спасибо.
The text was updated successfully, but these errors were encountered: