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

Queue Bundle Laravel Package

glorpen/queue-bundle

glorpen/queue-bundle is a Symfony bundle that wires message queue consumers into your application, letting you register workers and configure queue services through bundle configuration instead of boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

Step 0 — check the category before anything else. This is not a Laravel package. There is no ServiceProvider, no Facade, no config/queue-bundle.php, no publish tag, and nothing under an Illuminate\ namespace to hook into. It is a Symfony bundle (Glorpen\QueueBundle\GlorpenQueueBundle) wired through Symfony's DI container and YAML bundle configuration. Running composer require glorpen/queue-bundle in a Laravel app will give you an unmaintained, GPL-3.0 library that Laravel's package discovery ignores — it will sit in vendor/ doing nothing until you write the adapter yourself, at which point you own a fork.

Where to look first (10 minutes, read-only): If your goal is to understand the concept, read the bundle's task/handler registration — producers push a task onto a queue backend, consumers are plain DI services tagged as handlers, and a worker command drains the queue and dispatches Symfony events around job lifecycle and failure. That vocabulary — task, handler, worker, lifecycle event — is the only thing worth carrying over.

First use case — the one you actually have: "offload this slow write/send/render to a background worker." In Laravel that is three commands, no dependency:

php artisan make:job SendInvoiceEmail
// app/Jobs/SendInvoiceEmail.php
class SendInvoiceEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public int $tries = 5;
    public int $backoff = 30;

    public function __construct(public Invoice $invoice) {}

    public function handle(Mailer $mailer): void
    {
        $mailer->send(new InvoiceMail($this->invoice));
    }

    public function failed(Throwable $e): void
    {
        Log::error('invoice email failed', ['invoice' => $this->invoice->id, 'e' => $e]);
    }
}
dispatch(new SendInvoiceEmail($invoice))->onQueue('mail');

Then run a worker under supervisor: php artisan queue:work --queue=mail --tries=5 --timeout=60. That is the entire bundle's value proposition, delivered by the framework, with failed-job persistence, retries, backoff, and Supervisor/Horizon observability included.

Where to stop: do not attempt a Laravel adapter for this bundle. If a real requirement exists (a Symfony service producing work your Laravel app must consume), solve it at the transport layer — see Implementation Patterns.

Implementation Patterns

1. Direct substitution (the default). Map each bundle "service task" 1:1 to a job class. The bundle's handler service + task payload becomes Job class + constructor-promoted properties. Laravel's container resolves typed constructor dependencies in handle(), which is the same DI ergonomics the bundle advertises — you just get it natively.

2. If someone insists on a task-registry abstraction. The bundle's mental model (named task types → handler services) can be reproduced in ~40 lines without any dependency, if your domain genuinely benefits from string-keyed tasks (e.g. tasks submitted by external systems):

// app/Queue/TaskRegistry.php
final class TaskRegistry
{
    /** @var array<string, class-string> */
    private array $map = [
        'invoice.send'   => SendInvoiceEmail::class,
        'report.rebuild' => RebuildReport::class,
    ];

    public function dispatch(string $type, array $payload): void
    {
        $job = $this->map[$type] ?? throw new UnknownTaskException($type);
        dispatch(new $job(...$payload));
    }
}

Bound as a singleton; external producers submit {type, payload} to a thin controller. This is a small internal design decision, not a package decision — spec it against native primitives.

3. Lifecycle hooks → Laravel job events. The bundle's Symfony event-dispatch hooks for "job started / job failed" have first-party equivalents. Register in a QueueServiceProvider:

Queue::failing(function (JobFailed $event) {
    // $event->job, $event->exception, $event->connectionName
    Log::channel('queue')->error('job failed', [
        'job' => $event->job->resolveName(),
        'queue' => $event->job->getQueue(),
        'attempts' => $event->job->attempts(),
    ]);
});

Also available: Queue::before, Queue::after, Queue::looping. This is strictly richer than the bundle's hook surface and does not need to be reconciled with a second event dispatcher.

4. Queue-per-worker mapping. The bundle's YAML worker config maps to Laravel's config/queue.php connections + --queue= flags. Define named queues by cost class, not by domain: mail, exports, webhooks, then size your Supervisor pools to each. Keep the default default queue for low-priority work only.

5. Cross-runtime interop (the only legitimate reason to think about this bundle). If a Symfony service and your Laravel app must share work, do not share PHP code. Define a versioned JSON envelope and a real transport (Redis list/stream, SQS, AMQP):

{
  "v": 1,
  "type": "invoice.send",
  "id": "01HX...",
  "created_at": "2025-01-01T00:00:00Z",
  "payload": { "invoice_id": 42 }
}

Producers publish; each framework consumes with its own native worker (php artisan queue:work + laravel/framework's Redis driver on one side, Symfony Messenger on the other). Enforce the contract with a JSON Schema in a shared, language-neutral repo — not a Composer dependency.

6. Integration checklist for any queue work, regardless of origin:

  • Job implements ShouldQueue, uses SerializesModels, keeps the payload to IDs where possible.
  • Explicit $tries, $backoff, $timeout, and $maxExceptions — don't rely on defaults.
  • failed() or a global Queue::failing() handler that logs with a correlation ID.
  • php artisan queue:monitor mail:100,exports:50 on a schedule for depth alerting.
  • Horizon if Redis; otherwise Supervisor configs in version control with the deployment.

Gotchas and Tips

License is a hard stop for most teams. GPL-3.0 is strong copyleft. Linking it into a proprietary or SaaS codebase creates derivative-work exposure that legal typically rejects outright. If this ever becomes a live discussion, get the answer in writing before a spike, not after — remediation under release pressure is the most expensive possible outcome.

Unmaintained means you own it forever. No CVE path, no PHP 8.x compatibility work, no dependency-graph hygiene, no upstream to page at 2 a.m. An abandoned Composer package with a single historical maintainer is also a supply-chain surface — ownership transfer or compromise is undetectable by conventional review. Zero stars and zero dependents means zero production evidence at any scale: retry semantics, poison-message handling, and throughput are all unverified.

Composer will likely refuse it anyway. Expect PHP 5.6–7.x-era constraints and Symfony 2/3 pins. A five-minute composer require --dry-run glorpen/queue-bundle against PHP 8.2+ usually ends the evaluation without a design meeting.

Don't build the adapter. The tempting middle path — write a service provider, translate Symfony DI definitions, bridge the two event dispatchers — is net-new bespoke code with no upstream to rebase against. It is strictly more work than dispatching a job, and you inherit every problem above.

Serialization is the silent killer. Any queue payload coming from an old library is fragile across PHP runtime upgrades; in-flight jobs during a deploy are a live risk. If you inherit messages from this system, drain or dead-letter the queue before the PHP upgrade, and validate every payload schema on dequeue.

Silent enqueue failure. Without a maintained failed-job store, dropped tasks don't surface until a business process visibly breaks. Laravel's failed_jobs table plus queue:retry/queue:failed solves this natively — if you're interoperating, build the dead-letter queue and alert on its depth from day one.

Watch for event-name collisions if you do run both stacks side by side in one process (don't): Symfony's EventDispatcherInterface and Laravel's Illuminate\Contracts\Events\Dispatcher are different contracts with different listener semantics. This is a strong argument for keeping them in separate services.

Extension points are fork points. There is no supported plugin surface here. The only "extension" is vendoring the code into your repo, pinning a commit, and accepting that security fixes come from your team.

Migration, if a legacy Symfony app uses this bundle: inventory task types and payload shapes, freeze the wire format, stand up a parallel consumer on Symfony Messenger, dual-run with shadow consumption and output comparison, cut over per task type oldest-first, then decommission. Budget weeks. Add a dependency-policy check (e.g. a CI grep or composer why) so it can't be reintroduced.

Ramp-up reality: the API reads in a day — "add a task, run it later." The cost is trust: no docs, no tests, no Stack Overflow corpus, so every non-obvious behavior is source-reading. The equivalent Laravel job takes an afternoon and has a searchable answer for every failure mode you'll hit.

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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core