Skip to content

Instantly share code, notes, and snippets.

@ostark
Last active February 11, 2024 16:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ostark/e0444e3e231cc937a31908b651e845b3 to your computer and use it in GitHub Desktop.
Save ostark/e0444e3e231cc937a31908b651e845b3 to your computer and use it in GitHub Desktop.
Better signal handling for long running Jobs in Craft
<?php
class TerminationSignals extends \yii\base\Module
{
public function init()
{
parent::init();
// Listen to SIGTERM
// throw RuntimeException to stop the current job
// and trigger error handling
Event::on(
\yii\queue\cli\Queue::class,
\yii\queue\cli\Queue::EVENT_WORKER_START,
function(\yii\queue\cli\WorkerEvent $event) {
pcntl_async_signals(true);
pcntl_signal(SIGTERM, function () use ($event) {
throw new \Symfony\Component\Process\Exception\RuntimeException('Received SIGTERM. Will stop.');
});
}
);
// Handle RuntimeException for a job
// 1) Release
// 2) Push the same job but with a delay
Event::on(
\yii\queue\cli\Queue::class,
\yii\queue\cli\Queue::EVENT_AFTER_ERROR,
function(\yii\queue\ExecEvent $event) {
if ($event->error instanceof \Symfony\Component\Process\Exception\RuntimeException) {
$queue = \Craft::$app->getQueue();
$queue->release($event->id);
$queue->delay(30)->push($event->job);
}
}
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment