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

Gearman Bundle Laravel Package

mmoreram/gearman-bundle

Mmoreram GearmanBundle integrates Gearman with Symfony to run background jobs and asynchronous tasks. It helps define workers, manage job queues, and dispatch work from your PHP application using simple configuration and service-based worker definitions.

View on GitHub
Deep Wiki
Context7

Getting Started

Decision point first: this is a Symfony bundle (Mmoreram\GearmanBundle), not a Laravel package. It ships a Bundle class, a DI extension, and compiler passes, so composer require mmoreram/gearman-bundle into a Laravel app buys you nothing usable — no service provider, no config publish, no queue driver. Day-to-day leverage for a Laravel developer comes in two forms:

  1. Run it where it belongs (a small Symfony worker service) and call it over Gearman from Laravel, or
  2. Treat it as a reference implementation for worker discovery + CLI ergonomics, and hand-roll ~150 lines in Laravel (an artisan gearman:work command plus a thin client wrapper around ext-gearman).

Prerequisites either way:

# Server
docker run -d -p 4730:4730 --name gearmand artefactual/gearmand

# PHP extension (NOT the pure-PHP "gearman" composer lib)
pecl install gearman && docker-php-ext-enable gearman
php -m | grep gearman

Minimal Symfony-side flow (what "first use case" looks like):

composer require mmoreram/gearman-bundle   # v5.1.1 as of this writing
# config/packages/gearman.yaml
gearman:
    servers:
        localhost:4730: ~
namespace App\Worker;

use Mmoreram\GearmanBundle\Driver\Gearman;

class ImageWorker
{
    #[Gearman\Job(name: 'image.resize')]
    public function resize(string $payload): string
    {
        $data = json_decode($payload, true);
        // ... resize ...
        return json_encode(['ok' => true, 'path' => $data['out']]);
    }
}
bin/console gearman:worker:list          # discovery check — do this FIRST
bin/console gearman:worker:execute ImageWorker
bin/console gearman:call image.resize '{"src":"a.jpg","out":"b.jpg"}'

The first real use case is always the same: move something slow and non-interactive (thumbnailing, PDF generation, mail fan-out, webhook retries) out of the request cycle, and get a CLI you can supervise.

Before you composer require, check the dependency floor. v5.1.1 requires doctrine/annotations ^2.0. If anything else in the Symfony worker service still pins ^1.x, composer will resolve you back to v5.0.1 — decide deliberately which side wins rather than letting the solver pick.

Implementation Patterns

Worker class = job namespace. Each public method on a worker class becomes a Gearman function; the method name (or the attribute name) is what clients call. Grouping related jobs in one class is the idiomatic unit, because it maps 1:1 to a supervised process.

Discovery, not registration. The bundle scans worker classes (annotations/attributes, plus optionally tagged services) rather than making you wire every job in YAML. That is the feature worth copying in Laravel — a workers config array or attribute scan beats a hand-maintained registry. Prefer attribute-based discovery (#[Gearman\Job]) over docblock annotations: it needs no annotation reader at all, so the whole doctrine/annotations upgrade treadmill (which is exactly what 5.1.1 was) simply doesn't apply to you.

Client usage from your app code — inject the bundle's client service rather than instantiating \GearmanClient directly, so server config stays in one place:

public function __construct(private GearmanClient $client) {}

// fire and forget
$this->client->doBackground('image.resize', json_encode($payload));

// synchronous, with a result
$result = $this->client->doNormal('image.resize', json_encode($payload));

Rules of thumb I'd apply daily:

  • doBackground by default. Sync calls tie a web request to a worker; only use them for sub-100 ms jobs.
  • Payload is a single opaque string. JSON-encode an envelope (['id' => ..., 'v' => 1, 'data' => ...]) so you can evolve it. Never rely on positional args.
  • Use unique keys for idempotent dedupe (e.g. md5('resize:'.$imageId)) so a double-dispatch doesn't double-process.
  • One worker process per worker class, under supervisor/systemd, with iterations set so PHP recycles the process and bleeds memory/DB connections. Never run workers with daemonize semantics you don't control.

Bridging to Laravel. If you keep Gearman, the cleanest Laravel shape is a custom queue connector (Queue::extend) so dispatch() keeps working, plus an artisan gearman:work <worker> command that mirrors gearman:worker:execute. If you don't need Gearman specifically, Laravel's Redis/SQS queue already gives you what this bundle's CLI gives you, with retries and a failed-jobs table baked in — be honest about whether you're adopting Gearman because of an existing gearmand fleet or because of the bundle.

Gotchas and Tips

  • ext-gearman is a hard dependency and a common silent failure. Installing gearman/gearman from Packagist instead gets you a different API. If GearmanClient is "not found" at runtime, it's the extension.
  • v5.1.1 is dependency hygiene, not a feature release. The only change is the doctrine/annotations 2.0 bump plus the refactor needed to fit it. Read it as signal, not capability: nothing new to adopt, but it raises the floor on the annotation path.
  • doctrine/annotations 2.0 removed APIs that older bootstraps call. The deprecated AnnotationRegistry autoloading helpers are gone; annotation classes are resolved purely through composer autoloading now. If your worker-service bootstrap (or a bundle you copied it from) calls AnnotationRegistry::registerLoader(), it fatals on upgrade. Attributes sidestep this entirely.
  • Pinning tension is the real upgrade cost. Packages still on doctrine/annotations ^1.x will block v5.1.1. Check with composer why doctrine/annotations before bumping, and be prepared to hold at v5.0.1 in the worker service while you migrate the conflicting package — nothing in the wire protocol or job API changed, so mixed versions across services are fine.
  • No retries, no dead-letter queue, no failed-job table, no UI. The bundle is a thin client/worker wrapper. Everything Laravel's queue gives you for free — backoff, failed_jobs, queue:retry, Horizon-style metrics — you build yourself. Budget for it.
  • Long-running workers reuse the container. Stale entity manager, closed MySQL connections, growing in-memory caches. Bound the loop with iterations and let supervisor restart; treat a worker as disposable.
  • Symfony2 heritage in the docs. Examples still show docblock annotations and old directory layouts (app/console, Acme\DemoBundle). On modern Symfony use attributes and bin/console; the 5.1.1 refactor modernised the code behind those annotations but not the documentation around them.
  • Job-name collisions are invisible. image.resize declared in two worker classes is a race you'll debug at 2am. gearman:worker:list is your friend; grep job names in CI.
  • Return values must be serializable and fit Gearman's payload size limits (default ~1 MB per side). Big blobs go to S3/disk; pass a pointer.
  • Debug with the daemon, not the bundle: gearadmin --status, gearadmin --workers, gearadmin --show-jobs, plus gearmand -vvv. Run a worker in the foreground and var_dump before you blame the bundle.
  • Community signal is thin — 237 stars, effectively zero dependents, low opportunity score, and single-contributor PRs. The good news is 5.x is still receiving maintenance patches (5.0.1 → 5.1.1 is dependency upkeep, which is the right kind of patch). The bad news is still: read the source (it's small, MIT), expect to patch, and don't count on a quick answer to an issue.
  • Extension points, if you do extend it: custom job discovery, service-tagged workers, and event hooks around job execution are the seams. In a Laravel port, mirror these as an interface + app/Workers scan rather than fighting the Symfony DI compiler pass.
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.
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
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect