catch-of-the-day/php-resque-bundle
Installation Add the bundle via Composer:
composer require catch-of-the-day/php-resque-bundle
Register the bundle in config/app.php under providers:
CatchOfTheDay\ResqueBundle\ResqueServiceProvider::class,
Publish the default configuration (optional):
php artisan vendor:publish --provider="CatchOfTheDay\ResqueBundle\ResqueServiceProvider"
Basic Configuration
Edit config/resque.php to define your Redis connection and queue names:
'connections' => [
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
],
'queues' => [
'default' => 'default_queue',
],
First Job
Create a job class (e.g., app/Jobs/ProcessUser.php):
namespace App\Jobs;
use CatchOfTheDay\ResqueBundle\Job\JobInterface;
class ProcessUser implements JobInterface
{
public function perform($data)
{
// Your job logic here
\Log::info('Processing user: ' . $data['user_id']);
}
}
Enqueue a Job Dispatch the job in a controller or command:
use CatchOfTheDay\ResqueBundle\Facades\Resque;
Resque::enqueue('App\Jobs\ProcessUser', ['user_id' => 123]);
Run the Worker Start the Resque worker in a terminal:
php artisan resque:work default_queue
Job Dispatching
Resque::enqueue('App\Jobs\SendEmail', [
'to' => 'user@example.com',
'subject' => 'Welcome!',
]);
Resque::enqueueBulk([
['class' => 'App\Jobs\GenerateReport', 'args' => ['report_id' => 1]],
['class' => 'App\Jobs\GenerateReport', 'args' => ['report_id' => 2]],
]);
Resque::enqueueIn(60, 'App\Jobs\CleanupTempFiles'); // Delay by 60 seconds
Job Chaining
Use after to chain jobs:
Resque::enqueue('App\Jobs\ProcessOrder', ['order_id' => 1])
->after('App\Jobs\SendOrderConfirmation');
Job Prioritization Assign priorities (lower number = higher priority):
Resque::enqueue('App\Jobs\CriticalTask', [], 1); // Highest priority
Worker Management
php artisan resque:work default_queue --workers=4
php artisan resque:work high_priority_queue
Job Retries Implement retry logic in your job:
class ProcessPayment implements JobInterface
{
public function perform($data)
{
try {
// Payment logic
} catch (\Exception $e) {
if ($this->shouldRetry($e)) {
Resque::requeue($this->getJobId(), 5); // Retry in 5 seconds
}
}
}
}
Laravel Events Trigger jobs from Laravel events:
Event::listen('user.registered', function ($user) {
Resque::enqueue('App\Jobs\WelcomeEmail', ['user' => $user]);
});
Database Transactions Combine with Laravel transactions for atomicity:
DB::transaction(function () {
// Save data
Resque::enqueue('App\Jobs\PostProcessData', ['data_id' => $id]);
});
Monitoring Use Redis CLI to monitor queues:
redis-cli --scan --pattern "*queues*" | grep -v "scan"
Testing Mock jobs in tests:
$this->partialMock(Resque::class, ['enqueue']);
Resque::enqueue('App\Jobs\TestJob', []);
$this->assertTrue(true); // Verify enqueue was called
Redis Connection Issues
REDIS_HOST and REDIS_PORT in .env.php artisan resque:status to check connection.Job Serialization
Resque::enqueue('App\Jobs\ProcessUser', ['user' => $user->toArray()]);
Worker Stuck on Jobs
Resque::timeout() to set a timeout:
Resque::enqueue('App\Jobs\LongRunningTask', [], 300); // 5-minute timeout
php artisan resque:kill default_queue
Queue Locks
redis-cli DEL "resque:lock:job_class:job_id"
Job Class Naming
App\Jobs\ProcessUser).Log Job Execution
Add logging to your job’s perform method:
\Log::debug('Job executed with data: ' . json_encode($data));
Check Redis Directly Inspect queues and jobs:
redis-cli LRANGE default_queue 0 -1 # List all jobs in the queue
redis-cli HGETALL resque:job:job_id # Inspect a specific job
Worker Verbosity
Run workers with -v for debug output:
php artisan resque:work default_queue -v
Job Failures
Implement a failed method in your job to handle failures:
public function failed(\Exception $e)
{
\Log::error('Job failed: ' . $e->getMessage());
// Optionally send a notification
}
Environment-Specific Config
Use .env for Redis settings:
REDIS_HOST=redis.local
REDIS_PORT=6379
REDIS_DB=1
Custom Job Classes
Extend the base JobInterface for shared functionality:
abstract class BaseJob implements JobInterface
{
protected $maxRetries = 3;
public function shouldRetry(\Exception $e)
{
return $this->maxRetries-- > 0;
}
}
Middleware for Jobs Create middleware to pre/post-process jobs:
Resque::middleware(function ($job, $next) {
\Log::info("Processing job: {$job->class}");
return $next($job);
});
Custom Worker Classes Override the default worker behavior:
php artisan make:resque-worker CustomWorker
Then configure in config/resque.php:
'worker_class' => \App\Resque\CustomWorker::class,
Plugin System Extend the bundle by publishing and overriding views/templates (if any are included).
Event Listeners Listen for Resque events (e.g., job enqueued, job started):
Event::listen('resque.job.enqueued', function ($job) {
\Log::info("Job enqueued: {$job->class}");
});
How can I help you explore Laravel packages today?