Installation Add the package via Composer:
composer require ano/barbeq
Register the service provider in config/app.php:
'providers' => [
// ...
BarbeQ\BarbeQServiceProvider::class,
],
Configuration Publish the config file:
php artisan vendor:publish --provider="BarbeQ\BarbeQServiceProvider"
Edit config/barbeq.php to define your adapter (e.g., AMQP, PDO, or a custom one).
First Use Case: Sending a Message
Inject the BarbeQ facade into a service or controller:
use BarbeQ\Facades\BarbeQ;
public function sendMessage()
{
$message = new \BarbeQ\Model\Message([
'id' => 1,
'data' => ['foo' => 'bar'],
]);
BarbeQ::cook('queue_name', $message);
// or BarbeQ::publish('queue_name', $message);
}
First Use Case: Consuming a Message
Define a consumer class (e.g., app/Consumers/MyConsumer.php):
namespace App\Consumers;
use BarbeQ\Model\Message;
class MyConsumer
{
public function consume(Message $message)
{
// Process the message
\Log::info('Consumed: ' . $message->getData());
}
}
Register the consumer in a service provider:
public function register()
{
$this->app->make('BarbeQ')->addConsumer('queue_name', new MyConsumer());
}
Start consuming messages:
BarbeQ::eat('queue_name', 5); // Consume 5 messages
// or BarbeQ::consume('queue_name', 5);
Choosing an Adapter
Configure the desired adapter in config/barbeq.php:
'adapter' => [
'type' => 'amqp', // or 'pdo', 'custom'
'config' => [
'host' => 'localhost',
'exchange' => ['name' => 'test_direct'],
'queues' => [['name' => 'test']],
],
],
For PDO, define a table structure (e.g., queuing with id, payload, status columns).
Dynamic Adapter Switching Use Laravel's binding to dynamically switch adapters based on environment:
$this->app->bind('BarbeQAdapter', function ($app) {
if ($app->environment('local')) {
return new \BarbeQ\Adapter\PdoAdapter($app['db']->connection(), ['table' => 'queuing']);
}
return new \BarbeQ\Adapter\AmqpAdapter(
['host' => config('queue.connection.host')],
['name' => config('queue.connection.exchange')],
[['name' => config('queue.connection.queue')]]
);
});
Custom Adapters
Extend BarbeQ\Adapter\AbstractAdapter to create a new adapter:
namespace App\Adapters;
use BarbeQ\Adapter\AbstractAdapter;
use BarbeQ\Model\Message;
class RedisAdapter extends AbstractAdapter
{
protected $redis;
public function __construct(\Redis $redis)
{
$this->redis = $redis;
}
public function publish(Message $message, $queue)
{
$this->redis->rpush($queue, $message->getData());
}
public function consume($queue, $limit = 1)
{
$messages = $this->redis->lrange($queue, 0, $limit - 1);
// ... implement logic to return Message objects
}
}
Listening to Events Attach listeners to track message lifecycle:
BarbeQ::addListener('barbeq.pre_consume', function ($event) {
\Log::debug('Consuming message ID: ' . $event->getMessage()->getId());
});
BarbeQ::addListener('barbeq.post_consume', function ($event) {
if ($event->isAck()) {
\Log::info('Message acknowledged: ' . $event->getMessage()->getId());
}
});
Custom Events Dispatch custom events during message processing:
BarbeQ::addListener('barbeq.pre_consume', function ($event) {
event(new \App\Events\MessageConsuming($event->getMessage()));
});
Priority Consumers Use multiple consumers for the same queue with priority logic:
BarbeQ::addConsumer('high_priority_queue', new HighPriorityConsumer());
BarbeQ::addConsumer('high_priority_queue', new LowPriorityConsumer());
Batch Processing Process messages in batches with a custom consumer:
class BatchConsumer
{
public function consume(Message $message)
{
$batch = collect(json_decode($message->getData(), true));
$batch->each(function ($item) {
// Process each item in the batch
});
}
}
Delayed Messages Implement a delayed queue by extending the adapter or using metadata:
$message = new Message([
'data' => ['foo' => 'bar'],
'metadata' => ['delay' => time() + 3600], // Delay for 1 hour
]);
BarbeQ::cook('delayed_queue', $message);
Hybrid Approach Use BarbeQ for complex messaging and Laravel's queue system for simple jobs:
// For simple jobs
dispatch(new \App\Jobs\ProcessSimpleData);
// For complex messaging
BarbeQ::cook('complex_queue', new Message(['data' => $complexData]));
Queue Workers Run BarbeQ consumers as Laravel queue workers:
php artisan queue:work --queue=barbeq
Configure the worker to listen to BarbeQ events:
$worker = new \Illuminate\Queue\Worker($app['queue'], $app['events']);
$worker->daemonize();
$worker->loopUntil(function () {
BarbeQ::consume('queue_name', 1);
});
Adapter-Specific Quirks
declare methods if needed.
$adapter = new AmqpAdapter($connection, $exchange, $queues);
$adapter->declareExchange();
$adapter->declareQueues();
payload column for JSON data).Message Serialization
BarbeQ expects messages to be serializable. Use json_encode for complex data:
$message = new Message([
'data' => json_encode(['nested' => ['key' => 'value']]),
]);
Consumer Registration
Consumers must implement the consume(Message $message) method. Avoid circular dependencies when registering consumers in service providers.
Event Dispatcher Conflicts
Ensure the messageDispatcher and dispatcher in BarbeQ are unique instances to avoid event listener conflicts.
Memory Leaks
Large messages or batch processing can cause memory issues. Use unserialize() carefully and limit batch sizes:
BarbeQ::eat('queue_name', 10); // Process 10 messages at a time
Enable Logging Add listeners to log message flow:
BarbeQ::addListener('barbeq.pre_publish', function ($event) {
\Log::debug('Publishing to queue: ' . $event->getQueue(), ['message' => $event->getMessage()->getData()]);
});
Check Adapter Connection Verify the adapter is properly connected:
$adapter = app('BarbeQAdapter');
if ($adapter instanceof \BarbeQ\Adapter\AmqpAdapter) {
\Log::info('AMQP connection status:', ['connected' => $adapter->isConnected()]);
}
Handle Exceptions Wrap consumer logic in try-catch blocks to avoid silent failures:
public function consume(Message $message)
{
try {
// Process message
} catch (\Exception $e) {
\Log::error('Consumer error', ['message
How can I help you explore Laravel packages today?