Installation:
composer require amadeus-m/resque
Enable the bundle in config/bundles.php:
Amadeus\ResqueBundle\AmadeusResqueBundle::class => ['all' => true],
Configuration:
Add Redis connection details in config/packages/amadeus_resque.yaml:
amadeus_resque:
redis:
host: '127.0.0.1'
port: 6379
password: null
worker:
count: 4
log_file: '%kernel.logs_dir%/resque.log'
First Job:
Define a job class (e.g., src/Job/ProcessDataJob.php):
namespace App\Job;
use Resque\Job;
class ProcessDataJob extends Job
{
protected $data;
public function __construct($data)
{
$this->data = $data;
}
public function perform()
{
// Your logic here
\Log::info('Processing data: ' . $this->data);
}
}
Enqueue a Job:
Use the Resque service in a controller or command:
use Amadeus\ResqueBundle\Resque\Resque;
class SomeController extends AbstractController
{
public function __invoke(Resque $resque)
{
$resque->enqueue('App\Job\ProcessDataJob', ['data' => 'example']);
}
}
Run Workers: Start workers via CLI:
php bin/console resque:work
Job Dispatching:
Resque service in controllers, commands, or services.public function __construct(private Resque $resque) {}
public function queueTask($payload)
{
$this->resque->enqueue('App\Job\ProcessDataJob', $payload);
}
Delayed Jobs:
Use delay method for scheduled execution:
$resque->enqueue('App\Job\ProcessDataJob', ['data' => 'example'], 60); // Delay by 60 seconds
Worker Management:
resque:work command with --count flag.resque:restart to restart workers gracefully.Job Prioritization:
Enqueue jobs with custom queues (e.g., high_priority):
$resque->enqueue('App\Job\ProcessDataJob', ['data' => 'example'], 0, 'high_priority');
Error Handling:
Implement onFail in jobs for retries or logging:
public function onFail($exception)
{
\Log::error('Job failed: ' . $exception->getMessage());
}
Symfony Events:
Trigger jobs from Symfony events (e.g., KernelEvents::TERMINATE):
$eventDispatcher->addListener(KernelEvents::TERMINATE, function () use ($resque) {
$resque->enqueue('App\Job\CleanupJob', []);
});
Doctrine Integration: Use jobs for async database operations (e.g., batch processing):
public function processBatch($batchId)
{
$resque->enqueue('App\Job\BatchProcessJob', ['batch_id' => $batchId]);
}
Monitoring:
Use Redis CLI or tools like resque-web (external) to monitor queues:
redis-cli MONITOR
Testing:
Mock Resque service in PHPUnit:
$this->mockBuilder()
->disableOriginalConstructor()
->getMock()
->method('enqueue')
->willReturn(true);
Redis Connection Issues:
redis-cli ping
Worker Stuck on Jobs:
sleep() in loops).Resque::pause() or Resque::kill() for stuck workers (via CLI or custom commands).Queue Locking:
config/packages/amadeus_resque.yaml:
amadeus_resque:
worker:
timeout: 120 # 2 minutes
Job Serialization:
Serializable or use __sleep()/__wakeup().public function __sleep()
{
return ['data'];
}
Worker Logs:
var/log/resque.log by default. Rotate logs in production:
# config/packages/monolog.yaml
handlers:
resque:
type: rotating_file
path: '%kernel.logs_dir%/resque.log'
max_files: 7
Check Redis Queues:
redis-cli LRANGE resque:queue 0 -1
Worker Debugging:
php bin/console resque:work --verbose
STDERR logging for worker errors.Job Retries:
failed queue. Inspect with:
redis-cli LRANGE resque:failed 0 -1
php bin/console resque:requeue <job_class> <payload>
Performance:
htop or top).Custom Job Classes:
Extend Resque\Job for shared logic:
abstract class BaseJob extends Job
{
protected $logger;
public function __construct()
{
$this->logger = new \Monolog\Logger('jobs');
}
protected function log($message)
{
$this->logger->info($message);
}
}
Middleware:
Use Resque::addMiddleware() to intercept jobs (e.g., logging, auth):
$resque->addMiddleware(function ($job, $args) {
\Log::info('Job dispatched: ' . get_class($job));
});
Custom Commands:
Extend ResqueCommand for domain-specific tasks:
namespace App\Command;
use Amadeus\ResqueBundle\Command\ResqueCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class CustomResqueCommand extends ResqueCommand
{
protected function configure()
{
$this->setName('app:resque:custom');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->resque->enqueue('App\Job\CustomJob', ['data' => 'custom']);
$output->writeln('Custom job queued!');
}
}
Redis Configuration: Override Redis connection dynamically (e.g., per environment):
# config/packages/amadeus_resque.yaml (prod)
amadeus_resque:
redis:
host: '%env(REDIS_HOST)%'
port: '%env(int:REDIS_PORT)%'
How can I help you explore Laravel packages today?