simple-bus/asynchronous-bundle
Symfony bundle for asynchronous command/event handling with SimpleBus. Integrates async middleware and message dispatching so work can be queued and processed later. Part of the SimpleBus ecosystem; docs and issue tracking in the main repository.
Install the Bundle:
composer require simple-bus/asynchronous-bundle
Note: Since this is a Symfony bundle, Laravel integration requires a custom service provider or Symfony bridge (e.g., symfony/flex).
Create a Laravel Service Provider:
Register the bundle in config/app.php:
'providers' => [
// ...
SimpleBusLaravelServiceProvider::class,
],
Define the provider (app/Providers/SimpleBusLaravelServiceProvider.php):
use SimpleBus\AsynchronousBundle\SimpleBusAsynchronousBundle;
use Symfony\Component\HttpKernel\Kernel;
class SimpleBusLaravelServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->register(new SimpleBusAsynchronousBundle(), [
'kernel' => $this->app->make(Kernel::class),
]);
}
}
Configure the Message Store:
Edit config/packages/simple_bus_asynchronous.yaml (create if missing):
simple_bus_asynchronous:
message_store: 'doctrine://default' # or 'symfony://cache.app'
Laravel Note: Use doctrine if using Eloquent, or symfony://cache.app for file-based storage.
Define Your First Message:
Create a message class (e.g., app/Messages/ProcessOrder.php):
namespace App\Messages;
class ProcessOrder
{
public function __construct(public string $orderId) {}
}
Create a Handler:
Implement a handler (e.g., app/Handlers/ProcessOrderHandler.php):
namespace App\Handlers;
use App\Messages\ProcessOrder;
use SimpleBus\Message\Handler\MessageHandlerInterface;
class ProcessOrderHandler implements MessageHandlerInterface
{
public function handle(ProcessOrder $message)
{
// Business logic (e.g., dispatch a Laravel job)
ProcessOrderJob::dispatch($message->orderId);
}
}
Register the Handler:
In SimpleBusLaravelServiceProvider.php:
public function boot()
{
$this->app->bind(\SimpleBus\Message\Handler\MessageHandlerInterface::class, function ($app) {
return new \App\Handlers\ProcessOrderHandler();
});
}
Dispatch a Message:
use App\Messages\ProcessOrder;
use SimpleBus\Message\Bus\MessageBusInterface;
class OrderController extends Controller
{
public function __construct(private MessageBusInterface $bus) {}
public function store()
{
$this->bus->dispatch(new ProcessOrder('order-123'));
return response()->json(['status' => 'processing']);
}
}
Run the Queue Worker:
php artisan queue:work
Note: SimpleBus messages are not natively processed by Laravel’s queue system. You’ll need a custom queue listener (see Implementation Patterns).
namespace App\Messages;
class SendEmailNotification { public function __construct(public string $userId, public string $template) {} }
namespace App\Handlers;
use App\Messages\SendEmailNotification;
use Illuminate\Support\Facades\Mail;
class SendEmailNotificationHandler implements MessageHandlerInterface
{
public function handle(SendEmailNotification $message)
{
Mail::to($message->userId)->send(new EmailTemplate($message->template));
}
}
$this->bus->dispatch(new SendEmailNotification($user->id, 'welcome'));
// Controller dispatches a message; handler processes it asynchronously.
$this->bus->dispatch(new UpdateUserProfile($userId, $data));
public function handle(UpdateUserProfile $message)
{
UpdateProfileJob::dispatch($message->userId, $message->data);
}
namespace App\Messages;
class UserRegistered { public function __construct(public string $userId) {} }
public function handle(UserRegistered $event)
{
event(new UserRegisteredEvent($event->userId));
// Or: Log to a read model via Laravel's event system.
}
// SimpleBus message triggers a Laravel job.
public function handle(OrderCreated $message)
{
SendOrderConfirmationJob::dispatch($message->orderId);
}
Since SimpleBus doesn’t natively integrate with Laravel’s queue system, create a queue listener to consume SimpleBus messages:
Create a Queue Listener:
namespace App\Listeners;
use App\Messages\ProcessOrder;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class SimpleBusQueueListener implements ShouldQueue
{
use InteractsWithQueue;
public function handle(ProcessOrder $message)
{
// Process the message (e.g., call a handler).
}
}
Dispatch Messages to Laravel’s Queue: Modify your SimpleBus handler to push messages to Laravel’s queue:
public function handle(ProcessOrder $message)
{
SimpleBusQueueListener::dispatch($message);
}
SimpleBus uses PHP serialization by default. For Laravel compatibility, use JSON:
# config/packages/simple_bus_asynchronous.yaml
simple_bus_asynchronous:
message_store: 'doctrine://default'
serializer: 'json' # Override default
SimpleBus lacks built-in retries. Implement a handler wrapper:
namespace App\Handlers;
use SimpleBus\Message\Handler\MessageHandlerInterface;
use Illuminate\Support\Facades\Log;
class RetryableHandler implements MessageHandlerInterface
{
public function handle($message)
{
try {
$this->realHandler->handle($message);
} catch (\Exception $e) {
Log::error("Message failed: {$e->getMessage()}");
throw $e; // Laravel's queue will retry.
}
}
}
use App\Handlers\ProcessOrderHandler;
use App\Messages\ProcessOrder;
use PHPUnit\Framework\TestCase;
class ProcessOrderHandlerTest extends TestCase
{
public function testHandlesMessage()
{
$handler = new ProcessOrderHandler();
$message = new ProcessOrder('order-123');
$this->assertNull($handler->handle($message));
}
}
use App\Messages\ProcessOrder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class SimpleBusIntegrationTest extends TestCase
{
use RefreshDatabase;
public function testMessageProcessedAsynchronously()
{
$this->bus->dispatch(new ProcessOrder('order-123'));
$this->assertDatabaseHas('jobs', ['payload' => json_encode(['orderId' => 'order-123'])));
}
}
No Native Laravel Queue Support:
failed_jobs table. Use a custom listener to log failures:
public function handle($message)
{
try {
// ...
} catch (\Exception $e) {
\App\Models\FailedJob::create([
'message' => serialize($message),
'error' => $e->getMessage(),
]);
}
}
Serialization Mismatches:
simple_bus_asynchronous:
serializer: 'json'
Handler Registration Issues:
$this->app->bind(\SimpleBus\Message\Handler\MessageHandlerInterface::class, function ($app) {
return new \App\Handlers\ProcessOrderHandler
How can I help you explore Laravel packages today?