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

Resque Bundle Laravel Package

glit/resque-bundle

glit/resque-bundle is a Symfony bundle for integrating Resque, the Redis-backed PHP job queue. It helps wire Resque queues and workers into Symfony so applications can dispatch and process background jobs asynchronously.

View on GitHub
Deep Wiki
Context7

Getting Started

First, check the constraints before you write a line of code. Open composer.json in the repo. This bundle targets Symfony2 (app/console, AppKernel, symfony/symfony ~2.x, PHP 5.x). If you are on Laravel — or Symfony 4+ — you cannot install this. Treat the repo as a reference implementation of a php-resque integration and read DependencyInjection/Configuration.php, Command/, and Resources/config/services.xml for the wiring pattern. The conceptual map for a Laravel developer is direct:

This bundle Laravel equivalent
Resque::enqueue($queue, $class, $args) Queue::push(new Job($args))
glit:resque:worker:start php artisan queue:work
Redis resque:failed list failed_jobs table
php-resque-scheduler Queue::later()

If you are actually on Symfony2, the minimal path:

composer require glit/resque-bundle
# AppKernel.php
new Glit\ResqueBundle\GlitResqueBundle(),
# config.yml
glit_resque:
    redis:
        host: 127.0.0.1
        port: 6379
        database: 0   # give this app its own DB — see Gotchas

Write the smallest possible job — a plain class with a perform() method; php-resque instantiates it by string name, so it must be autoloadable and have a no-arg constructor:

class SendWelcomeEmailJob
{
    public $args;              // php-resque injects this

    public function perform()
    {
        $userId = $this->args['user_id'];
        // do the slow thing
    }
}

Enqueue from a controller or service, then run a worker:

php app/console glit:resque:worker:start default --interval=5

First use case: take one slow, non-user-facing side effect (welcome email, thumbnail generation, third-party sync) out of the request cycle. Don't start with retries, scheduling, or batches — get one job round-tripping through Redis and a supervised worker first.

Implementation Patterns

Keep the job class a dumb adapter. This is the single most important pattern. The job's perform() should resolve a service and delegate:

class SyncOrderJob
{
    public $args;

    public function perform()
    {
        $container = /* whatever hook the bundle gives you */;
        $container->get('app.order_sync')->sync($this->args['order_id']);
    }
}

Business logic lives in AppBundle\Service\OrderSync, which is unit-testable without Redis and portable to Laravel's Queue::push later. If you write logic inside perform(), you have coupled your domain to a 2013-era fork model.

Payloads must be JSON scalars. Only strings, ints, floats, bools, arrays, nulls. No entities, no DateTime objects, no binary. Pass IDs and re-fetch inside the job:

Resque::enqueue('mail', 'SendWelcomeEmailJob', ['user_id' => $user->getId()]);

Passing serialized entities is the classic mistake — the entity is stale by the time the worker picks it up, and Doctrine will hand you a detached object.

Split queues by latency class, not by feature. default for anything user-triggered, mail for bulk sends, exports for long-running work that can starve everything else. Then give each queue its own supervised worker group so an export can't block a password reset email.

Supervise with Supervisor, one program per queue:

[program:resque-default]
command=php /var/www/app/console glit:resque:worker:start default --interval=5
numprocs=2
process_name=%(program_name)s_%(process_num)02d
autostart=true
autorestart=true
stopsignal=QUIT
stdout_logfile=/var/log/resque-default.log

stopsignal=QUIT matters: php-resque handles SIGQUIT gracefully (finish current job, then exit) while SIGTERM kills mid-job. Using SIGTERM guarantees you will eventually see a job that is half-done and gets retried by nobody.

Design for idempotency from day one. php-resque has no retry/backoff and no --tries; a failed job lands in the Redis failed list and stays there. That does not mean jobs run once — a worker killed mid-perform() leaves the job in the queue's "in-progress" state and it will be reprocessed. Every perform() should be safe to run twice: check-then-act, or use a lock key in Redis.

Dispatch through a thin interface, not Resque::enqueue scattered everywhere. One JobDispatcher service with dispatch($queue, $class, $args) means you can swap the backend, log every enqueue, and fake the dispatcher in tests:

$dispatcher->dispatch('mail', SendWelcomeEmailJob::class, ['user_id' => 42]);

Migration tip: because payloads are JSON scalars and logic lives in services, moving to Laravel later is mechanical — dispatch() becomes Queue::push(), and the job classes get a handle() that calls the same service.

Gotchas and Tips

Doctrine connections die inside long-running workers. The worker process boots the kernel once and keeps running for days. MySQL drops idle connections after wait_timeout (default 8h), and the next job throws "MySQL server has gone away." Mitigate with a short --interval (keeps the connection warm) and explicit cleanup at the end of perform():

$em = $container->get('doctrine')->getManager();
$em->clear();                        // kill the identity map — it will grow forever otherwise
$em->getConnection()->close();       // forces a clean reconnect next job

The identity-map leak is the sneakier bug: memory climbs steadily and you blame PHP, when it's a thousand hydrated entities nobody released.

Redis key collisions. php-resque writes unprefixed keys: resque:queue:default, resque:workers, resque:stat:processed. Two apps on the same Redis database will steal each other's jobs and corrupt each other's worker registry. Always isolate by database index or a dedicated Redis instance. There is no configurable namespace.

Job class names are strings that live in Redis. Rename or delete SendWelcomeEmailJob while jobs are queued and the worker throws CouldNotLoadJob. Treat job class names as a public API: deprecate rather than rename, and keep a stub class that delegates to the new name.

The backend is a static global. Resque::setBackend() is process-wide. The bundle sets it during kernel boot, so enqueueing from inside Symfony works — but any standalone script, cron entry, or test that calls Resque::enqueue outside the kernel must call setBackend() itself or jobs silently go to localhost:6379/0.

Stale workers wedge your monitoring. Workers register themselves in the resque:workers set and clean up on graceful exit. kill -9 (or an OOM kill) leaves a ghost entry forever, and anything that reads worker counts will lie to you. Check the set directly when debugging:

redis-cli smembers resque:workers
redis-cli llen resque:queue:default
redis-cli lrange resque:failed 0 10

Failures are invisible by default. Nothing retries, nothing alerts. If you keep this stack, add a small cron that polls resque:failed, logs the count to your metrics, and replays selected jobs. Otherwise a broken job silently accumulates for weeks.

No container injection by default. php-resque does new $class, so your job gets no constructor arguments. Look in the bundle's Resources/config/ for how it hooks job instantiation; the usual extension point is to implement ContainerAwareInterface on the job and let the bundle's job factory set the container, or to define your own abstract base job class that pulls services from a statically-stashed container. Verify which one this version supports before designing around it — this is where bundle forks diverge most.

Debug a single job synchronously by instantiating it and setting $args by hand. Do not debug through Redis; you will waste hours on serialization when the bug is in your service.

Windows is a non-starter. php-resque forks via pcntl_fork. Linux/macOS only.

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.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib