eo/job-queue-bundle
MongoDB ODM implementation for JMSJobQueueBundle that lets you schedule Symfony2 console commands as background jobs. Requires Symfony 2.1+ and one supervisord-managed eo-job-queue:run process, with a configurable job class.
Before you write any code, do the reality check: this is a Symfony 2.1+ bundle, not a Laravel package. There is no ServiceProvider, no facade, no config/job-queue.php, and no Composer auto-discovery. A Laravel developer "leverages" it in one of two ways:
Queue + Artisan::call() + a MongoDB-backed queue driver.Symfony\Component\Process\Process.Where to look first
Eo\JobQueueBundle\Console\Application — the class the README tells you to swap into app/console. This is the seam where a "console app" becomes a "queue-aware console app."JMSJobQueueBundle upstream docs — Eo is the MongoDB ODM persistence layer; scheduling semantics, worker commands, and job lifecycle live upstream.composer.json — verify the Symfony and Doctrine MongoDB ODM constraints against your PHP version; this bundle predates modern PHP.Minimal first use case: schedule one existing console command as a persisted job.
composer require eo/job-queue-bundle:dev-master
// app/AppKernel.php
new Eo\JobQueueBundle\EoJobQueueBundle(),
// app/console
use Eo\JobQueueBundle\Console\Application; // replaces Symfony\Bundle\FrameworkBundle\Console\Application
Then configure the job/document class per the README and enqueue a command. Confirm you can run the queue worker and see the job document persisted in the jobs collection before wiring anything else.
Pattern 1 — Symfony-native scheduling (if you're actually on Symfony).
Register commands normally, enqueue them as jobs, and run the worker as a supervised daemon (supervisord/systemd). Treat the MongoDB collection as the source of truth for job state (pending/running/finished/failed) and build dashboards on top of it. Because the console Application class is replaced, every command in that kernel can be scheduled — that's the whole value proposition.
Pattern 2 — Laravel orchestrator, Symfony worker (bridge). Keep Laravel as the app, run this bundle in a small Symfony console service. From Laravel:
use Symfony\Component\Process\Process;
$process = new Process(['php', '/path/to/symfony/app/console', 'acme:report:generate', '--since=2024-01-01']);
$process->setTimeout(3600);
$process->run();
Dispatch that from a queued Laravel job so retries, backoff, and failed-job handling stay in Laravel where your team already has tooling.
Pattern 3 — Reimplement the concept in Laravel (recommended for greenfield). This is usually the right call:
// A job document mirrors Eo's model
class RunConsoleCommand implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(
public string $command,
public array $arguments = [],
) {}
public function handle(): void
{
$exit = \Artisan::call($this->command, $this->arguments);
if ($exit !== 0) {
throw new \RuntimeException("Command {$this->command} exited {$exit}: " . \Artisan::output());
}
}
}
Persist a companion record in MongoDB (or Eloquent) for status, start/finish timestamps, and captured output — that's the piece Eo/JMS gives you for free and Laravel doesn't.
Integration tips
Artisan::call() if the Symfony service is down.No Laravel integration exists. Instantiating this bundle outside a booted Symfony kernel is painful — the DI container, bundle registration, and AppKernel are all assumed. Don't try to new EoJobQueueBundle() from a Laravel provider.
dev-master only. No tagged releases, 3 stars, 0 dependents. Pin the commit hash in composer.json, vendor the relevant classes if you must, and assume no upstream fixes. Check the depending.in badge for dependency health before committing.
Global console class swap. Replacing app/console's Application affects every console invocation in that project, including ones unrelated to the queue. Verify normal commands still behave (exit codes, input handling) after the swap.
MongoDB ODM version coupling. This targets old Doctrine MongoDB ODM. Modern mongodb/mongodb + doctrine/mongodb-odm will almost certainly conflict. Test the dependency resolution in isolation before adding it to a real project.
The worker is your responsibility. There is no Horizon, no pulse dashboard, no queue:work supervisor out of the box. You need supervisord (or systemd) plus your own monitoring for stuck/running jobs. Add a heartbeat and a stale-job reaper.
Job lifecycle hooks are upstream. Events, retry policies, and failure semantics come from JMSJobQueueBundle, not Eo. Read those docs — the Eo README won't tell you how retries work.
Custom job class is the primary extension point. The Step 4 config lets you swap the document class. Subclass it, add fields (tenant id, correlation id, priority), and keep the mapping annotation/XML in sync — a mismatched mapping fails at runtime, not at boot.
Debugging order for a job that never runs:
db.jobs.find())Application swap break argument parsing?Output capture. Command output and exit codes are easy to lose. Wrap execution so non-zero exits throw and get recorded, otherwise failed jobs look successful.
Don't scale this by adding workers blindly. MongoDB ODM document locking (if any) and the JMS worker model may not be concurrency-safe out of the box — verify before running multiple workers against one collection.
How can I help you explore Laravel packages today?