Installation:
composer require dubture/async-bundle
Ensure JMS\DiExtraBundle and JMS\AopBundle are registered in AppKernel.php (Symfony2).
Configure Backend:
Add to config.yml:
dubture_async:
backend: rabbitmq # or resque|sonata|runtime
For RabbitMQ, install php-amqplib and configure connection in config.yml:
dubture_async:
backend: rabbitmq
rabbitmq:
host: localhost
port: 5672
user: guest
password: guest
First Use Case: Annotate a method to run asynchronously:
use Dubture\AsyncBundle\Annotation\Async;
class MediaTranscodingService
{
/**
* @Async
*/
public function transcodeFile($sourcePath) {
// Heavy logic here
}
}
Call the method normally—it will queue the job automatically.
Annotation-Based Dispatch:
Use @Async on methods to offload execution. Supports optional parameters:
/**
* @Async(priority=5, delay=10) // Delay in seconds
*/
public function processOrder(Order $order) { ... }
Service Integration:
Inject Dubture\AsyncBundle\AsyncService to manually dispatch jobs:
$asyncService = $this->get('dubture_async.async_service');
$asyncService->dispatch('media_transcoder', 'transcodeFile', [$filePath]);
Backend-Specific Patterns:
config.yml:
dubture_async:
rabbitmq:
exchange: async_exchange
queue: async_queue
dubture_async:
resque:
redis: redis://localhost:6379
Result Handling:
Use @Async(return=true) to fetch results via a callback (backend-dependent):
/**
* @Async(return=true)
*/
public function generateReport() { ... }
Retrieve results with:
$result = $asyncService->getResult($jobId);
Error Handling:
Implement Dubture\AsyncBundle\AsyncJobListenerInterface to handle failures:
class AsyncErrorListener implements AsyncJobListenerInterface
{
public function onError($job, \Exception $e) {
// Log or retry logic
}
}
Register in services.yml:
services:
async_error_listener:
class: AppBundle\AsyncErrorListener
tags:
- { name: dubture_async.listener }
Backend Compatibility:
runtime backend (local PHP processes) is not recommended for production due to lack of persistence.Annotation Caching:
Clear Symfony’s cache (php app/console cache:clear) after adding/removing @Async annotations.
Priority/Delay Limits:
Result Persistence:
Circular Dependencies:
Avoid annotating methods that call other @Async methods directly—it may cause deadlocks or infinite queues.
Queue Inspection:
php-amqplib tools or management UI to check queues.redis-cli to inspect queues:
redis-cli LRANGE resque:queue:default 0 -1
Logging:
Enable debug mode in config.yml:
dubture_async:
debug: true
Logs job dispatching and errors to app/logs/dev.log.
Job Retries:
Configure retry logic in config.yml:
dubture_async:
retry:
max_attempts: 3
delay: 300 # seconds
Custom Backends:
Extend Dubture\AsyncBundle\Backend\AbstractBackend to support new backends (e.g., AWS SQS).
Job Serialization:
Override serialization in config.yml:
dubture_async:
serializer: AppBundle\Serializer\CustomSerializer
Middleware:
Add preprocessing/postprocessing with Dubture\AsyncBundle\AsyncJobMiddlewareInterface:
class LoggingMiddleware implements AsyncJobMiddlewareInterface
{
public function preDispatch($job) { /* ... */ }
public function postDispatch($job, $result) { /* ... */ }
}
Register in services.yml:
services:
async_logging_middleware:
class: AppBundle\LoggingMiddleware
tags:
- { name: dubture_async.middleware }
Dynamic Backend Selection: Use a parameter to switch backends dynamically:
parameters:
async_backend: %kernel.env.ASYNC_BACKEND% # e.g., "rabbitmq" or "resque"
Then reference it in config.yml:
dubture_async:
backend: %async_backend%
How can I help you explore Laravel packages today?