## Getting Started
### Minimal Setup
1. **Installation**:
```bash
composer require atexo/job-queue-bundle
Register the bundle in config/bundles.php:
return [
// ...
Atexo\JobQueueBundle\AtexoJobQueueBundle::class => ['all' => true],
];
Configure the Bundle:
Update config/packages/atexo_job_queue.yaml (auto-generated after installation):
atexo_job_queue:
queue_name: 'default' # Default queue name
storage:
type: 'doctrine' # Options: 'doctrine', 'file', 'database'
# Doctrine config (if using ORM)
doctrine:
entity: 'App\Entity\JobQueue' # Custom entity class
connection: 'default'
# File config (if using filesystem)
file:
directory: '%kernel.project_dir%/var/job_queue'
First Use Case: Annotate a Symfony command to run as a background job:
use Atexo\JobQueueBundle\Annotation\Job;
class MyBackgroundCommand extends Command
{
/**
* @Job(queue="default", delay=60) // Runs in 60 seconds
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
// Your command logic
return Command::SUCCESS;
}
}
Run the Worker: Start the job queue worker in a separate terminal:
php bin/console atexo:job-queue:worker
Scheduling Jobs:
@Job annotation to define queue and delay:
/**
* @Job(queue="high_priority", delay=3600) // Runs in 1 hour
*/
JobQueueClient service:
$client = $container->get('atexo.job_queue.client');
$client->schedule('app:my_command', ['arg1' => 'value'], 'default', 60);
Handling Job Results:
JobQueueListener to process job results:
use Atexo\JobQueueBundle\Event\JobEvent;
public function onJobCompleted(JobEvent $event)
{
if ($event->getExitCode() !== 0) {
// Handle failure
}
}
services.yaml:
services:
App\EventListener\JobListener:
tags:
- { name: 'kernel.event_listener', event: 'atexo.job_queue.job.completed', method: 'onJobCompleted' }
Retry Logic:
config/packages/atexo_job_queue.yaml:
atexo_job_queue:
retry:
enabled: true
max_attempts: 3
delay: 300 # 5 minutes between retries
Bulk Processing:
batch option to group jobs:
/**
* @Job(queue="batch", batch=true, batch_size=10)
*/
BatchAwareInterface.Dependency Injection:
public function __construct(private MyService $myService) {}
/**
* @Job(queue="default")
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$this->myService->doSomething();
return Command::SUCCESS;
}
With Doctrine:
JobQueue entity extends Atexo\JobQueueBundle\Entity\JobQueue:
use Atexo\JobQueueBundle\Entity\JobQueue as BaseJobQueue;
class JobQueue extends BaseJobQueue {}
config/packages/doctrine.yaml to include the entity:
orm:
mappings:
app:
type: annotation
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
With Supervisor:
[program:jobqueue-worker]
command=php /path/to/bin/console atexo:job-queue:worker
autostart=true
autorestart=true
user=www-data
numprocs=1
redirect_stderr=true
stderr_logfile=/var/log/jobqueue-worker.err.log
With Symfony Messenger:
# config/packages/messenger.yaml
framework:
messenger:
transports:
async: '%env(MESSENGER_TRANSPORT_DSN)%'
routing:
'Atexo\JobQueueBundle\Message\JobMessage': async
Testing:
JobQueueClient in tests:
$client = $this->createMock(JobQueueClient::class);
$client->expects($this->once())
->method('schedule')
->with('app:command', ['arg' => 'value'], 'queue', 0);
$this->container->set('atexo.job_queue.client', $client);
Worker Stuck on Jobs:
JobListener to log failures and ensure commands exit properly:
public function onJobFailed(JobEvent $event)
{
$this->logger->error('Job failed', [
'command' => $event->getCommand(),
'exit_code' => $event->getExitCode(),
'output' => $event->getOutput(),
]);
}
Queue Not Processing:
var/log/jobqueue-worker.log.file storage).doctrine storage).Annotation Not Recognized:
jms_serializer or incorrect annotation import.jms/serializer-bundle and ensure annotations are imported:
use Atexo\JobQueueBundle\Annotation\Job;
Delayed Jobs Not Respecting Delay:
polling_interval in config:
atexo_job_queue:
polling_interval: 10 # seconds
Memory Leaks:
setTimeout in the annotation or config:
atexo_job_queue:
timeout: 300 # 5 minutes
Enable Verbose Logging:
php bin/console atexo:job-queue:worker --verbose
Or in config/packages/monolog.yaml:
handlers:
job_queue:
type: stream
path: '%kernel.logs_dir%/job_queue.log'
level: debug
Inspect Queue State:
php bin/console doctrine:query:sql "SELECT * FROM job_queue"
ls -la %kernel.project_dir%/var/job_queue/
Simulate Failures:
throw new \RuntimeException('Test failure');
Custom Storage:
Atexo\JobQueueBundle\Storage\StorageInterface:
class CustomStorage implements StorageInterface
{
public function enqueue(Job $job): void { /* ... */ }
public function dequeue(): ?Job { /* ... */ }
public function delete(Job $job): void { /* ... */ }
}
config/packages/atexo_job_queue.yaml:
atexo_job_queue:
storage:
type: 'custom'
service: 'app.custom_storage'
Custom Job Entity:
Atexo\JobQueueBundle\Entity\JobQueue and add fields:
/**
* @ORM\Entity
*/
class CustomJobQueue extends JobQueue
{
/**
* @ORM\Column(type="string", nullable=true)
*/
private $customField;
}
How can I help you explore Laravel packages today?