Implementing a single-worker queue module in a load-balanced environment #12337
-
This is related to #11507 and some of #9905. We have a couple load-balanced Craft sites that have Here's how this process works:
Due to our hosting setup step 1 won't always grab the same web server. It just grabs a single server from the pool. That means the next time this process runs it could introduce a second queue worker (if it hits a different server). Ideally we'd setup a single server responsible for the queue, but we're unable to do that based on the current infrastructure. Instead, I was hoping to solve this with a bit of code. Here's what I was thinking:
Like so: class Queue extends Controller
{
public function actionRun()
{
// Exit if there are running jobs
if (Craft::$app->getQueue()->getHasReservedJobs()) {
ExitCode::OK;
}
// Otherwise run the queue as normal
Craft::$app->getQueue()->run();
ExitCode::OK;
}
} Would this solution work as a workaround to our infrastructure setup? Or is there something I'm missing? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 8 replies
-
Instead I’ve added support for a new Couple examples: php craft up --isolated php craft queue/listen --verbose --isolated php craft gc --isolated |
Beta Was this translation helpful? Give feedback.
-
Hey @brandonkelly — I noticed something about #12350. When you call... if (!Craft::$app->getMutex()->acquire($name)) {
$this->stderr("The $uniqueId command is already running.\n", Console::FG_RED);
return false;
} ...it will correctly check if the given command is running, but the Yii2 mutex-redis package has a default TTL of 30 seconds. If your queue is ran every minute via a cron, the I wonder if this feature needs to somehow alter the TTL so those locks can persist until the task has truly finished? |
Beta Was this translation helpful? Give feedback.
getHasReservedJobs()
can be a little unreliable if a job resulted in a fatal error (e.g. a resource limit was exceeded).Instead I’ve added support for a new
--isolated
option to all CLI commands for Craft 4.4 (#12350), which can be passed to ensure the command is only run once at a time. Any duplicate runs will be aborted withThe <command name> command is already running.
output to stderr and exit code1
.Couple examples: