Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Symfony Gearman Bundle Laravel Package

laelaps/symfony-gearman-bundle

Symfony bundle that integrates the Gearman job queue into your application. Configure servers, register workers and clients as services, dispatch background jobs, and handle results through a clean, framework-native API.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony 2-era bundle (now tagged 1.0.0) that wires the PECL gearman extension into the Symfony container. Note the release's framing: the 1.x line is explicitly maintained for PHP 5.3 compatibility, and a 2.x branch with a different API is planned (likely PHP 5.5+). That tells you everything about the target environment — this is not a package you adopt for new PHP 8 work. Before touching PHP, make sure the infrastructure exists: a running gearmand and the ext-gearman PECL extension loaded in your SAPI/CLI.

Minimal setup:

# Pin to the 1.x line explicitly; 2.x will be an API break when it lands
composer require "laelaps/symfony-gearman-bundle:^1.0"
// app/AppKernel.php (Symfony 2 style)
$bundles = [
    // ...
    new Laelaps\Symfony\GearmanBundle\LaelapsGearmanBundle(),
];
# app/config/config.yml — illustrative; verify exact key/node names
laelaps_gearman:
    servers:
        - { host: 127.0.0.1, port: 4730 }

Where to look first, in this order:

  1. DependencyInjection/Configuration.php — the authoritative config tree (server list, timeouts, service options). Don't trust blog posts; this file is the source of truth for the YAML shape.
  2. Resources/config/services.xml (or *.yml) — the actual service IDs for the client/worker. The README may reference slightly different IDs than what is registered.
  3. Command/ — any bundled console command for running workers. This is what you'll wire into Supervisor.
  4. README.md — for the intended producer/consumer workflow, and CHANGELOG/tags to confirm whether you're on 1.x or a 2.x pre-release.

First use case to validate the integration end-to-end: dispatch a background job from a controller and consume it from a CLI worker. Something like:

// Producer (controller/service)
$client = $this->container->get('gearman.client'); // confirm ID in services.xml
$client->doBackground('app.report.generate', json_encode(['reportId' => $id]));
// Consumer (worker command or standalone script)
$worker = $this->container->get('gearman.worker');
$worker->addFunction('app.report.generate', function (\GearmanJob $job) {
    $payload = json_decode($job->workload(), true);
    // ... do work ...
    $job->sendComplete('ok');
});
while ($worker->work()) {
    if ($worker->returnCode() !== GEARMAN_SUCCESS) {
        // log and decide whether to continue
    }
}

If that round trip works, the bundle is integrated; everything else is application architecture.

Implementation Patterns

Treat the bundle as a thin transport, not a job framework. It gives you client/worker services and (probably) a worker command. You own job names, payload schemas, retries, and observability.

Producer side (web requests):

  • Keep controllers thin: dispatch and return. Never do heavy work inline.
  • Namespace job names as routing keys: app.report.generate, app.email.send, app.import.run. This makes gearadmin --status readable.
  • Prefer doBackground() for fire-and-forget and doNormal()/doHigh()/doLow() when the caller needs a result or priority handling.
  • Serialize payloads explicitly as JSON with a version field ({"v":1, ...}) so producers and consumers can evolve independently. Never rely on PHP serialize() of objects.

Consumer side (CLI workers):

  • Wrap worker logic in your own service (ReportJobHandler), then register the callback in a command. This keeps handlers unit-testable and lets you reuse them outside Gearman.
  • Run workers as long-lived processes under Supervisor/systemd, not as cron one-shots.
  • For synchronous jobs, use sendData() for progress/intermediate data and sendComplete()/sendFail() to terminate cleanly.
  • Register multiple functions per worker process when they share dependencies and traffic profile; split into separate worker pools when one job type can starve another.
; supervisor example
[program:gearman-report-worker]
command=php app/console gearman:worker:run app.report.generate
numprocs=2
autorestart=true
stopwaitsecs=30

Integration tips:

  • Inject the client service into your producer services rather than pulling from the container.
  • If the bundle supports tagged worker services or annotations, use them—but verify against services.xml, since this bundle predates modern autoconfiguration.
  • For local development, run gearmand -vvv in a terminal and dispatch against it; it's the fastest way to see job names and payloads.

Gotchas and Tips

This is legacy software, and that's the biggest gotcha. The 1.0.0 release makes the situation explicit rather than fixing it: 1.x is frozen to a PHP 5.3-compatible codebase, which means Symfony 2.x-era APIs, no short-array/modern syntax guarantees, and no room for the bundle to adopt newer Symfony components. The PECL gearman extension itself is end-of-life and does not build cleanly (or at all) on modern PHP 7.4+/8.x. If you're on PHP 8, you cannot run this package's native Gearman calls without a fork or a different transport. Read composer.json constraints before planning anything.

Plan for the 1.x → 2.x split now. The release notes announce an incoming 2.x branch with a different API and (probably) a PHP 5.5 floor. Practical consequences:

  • Pin "laelaps/symfony-gearman-bundle": "^1.0" (or an explicit tag) — a floating constraint will silently pull a 2.x release with breaking service IDs/config shape.
  • 1.x is a maintenance branch: expect the PHP 5.3 constraint to block bug fixes that require anything newer. If you need a patch, you may have to fork.
  • Don't design your application code against the bundle's service IDs directly (see the wrapper advice below), or the 2.x migration becomes a rewrite instead of a version bump.

Worker processes are long-running, so state rots.

  • Doctrine connections go stale or time out; reconnect or use EntityManager::clear() periodically.
  • Memory leaks accumulate (especially with logging and Doctrine identity map); recycle workers after N jobs or on a time limit.
  • The Symfony container is frozen; don't expect config or service changes to appear without a restart.

Gearman has no built-in retries, backoff, or dead-letter queue. If a worker throws, the job can be lost or silently requeued depending on timing and return codes. Implement retry counting in the payload (or a DB table), cap attempts, and route exhausted jobs to a failure queue/table. Make handlers idempotent—at-least-once delivery means duplicates happen.

Exceptions inside the callback are dangerous. An uncaught exception can kill the worker loop mid-job. Wrap handlers in try/catch, always call sendFail() or sendComplete(), log with the job handle, and let Supervisor restart the process.

Configuration quirks.

  • Multiple servers mean failover, not load balancing—verify how the bundle passes the list to GearmanClient::addServer().
  • Timeouts are per-client and often default to "infinite"; set them explicitly for synchronous jobs.
  • Service IDs and config keys in old bundles frequently drift from the README. Grep the DependencyInjection and Resources/config directories rather than trusting docs. This is doubly true across the 1.x/2.x boundary, where the notes warn of a different API.

Debugging toolkit:

  • gearadmin --status / gearadmin --workers for queue depth and connected workers.
  • gearman -f app.report.generate -- '{"reportId":1}' to invoke a job manually and bypass your producer.
  • gearmand -vvv for wire-level logging.
  • Log the job handle ($job->handle()) in both producer and consumer so you can correlate dispatches with executions.

Extension points: because the bundle is thin, the cleanest customization is to leave its services alone and wrap them in your own JobDispatcher and WorkerRunner services. Override service definitions in your app config only when you need to change connection behavior; otherwise keep your code independent so a future migration off this bundle (to Symfony Messenger, Enqueue, or a hosted queue) — or onto the announced 2.x line — is a swap of two classes rather than a rewrite.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource