Event Bus Patterns
debt(d5/e5/b7/t7)
Closest to 'specialist tool catches it' (d5). The detection_hints list phpstan and psalm as the tools, and the code_pattern describes string event names vs typed classes and missing type-hints — these are precisely the kinds of issues that static analysis tools catch but default linters and compilers miss. The automated flag is yes, but only with specialist configuration.
Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix describes moving to typed event classes (e.g. Symfony EventDispatcher with named event classes), but common_mistakes reveal deeper issues: cross-service communication misuse, missing error handling in listeners, synchronous slow operations, and missing Outbox Pattern. Correcting a single misuse (string → class) is a small refactor, but fixing architectural misuse (in-process for cross-service, adding outbox pattern) touches multiple files and components — overall e5 fits.
Closest to 'strong gravitational pull' (b7). The applies_to covers all three contexts (web, cli, queue-worker) and the tags include 'architecture'. An event bus choice shapes how all decoupled operations are wired together across the codebase — every new feature that needs async or decoupled behaviour must conform to the chosen event bus pattern. Misusing in-process vs broker compounds over time as more listeners accumulate, making migration progressively harder.
Closest to 'serious trap' (t7). The misconception field explicitly states that developers confuse in-process event buses with message brokers — treating them as interchangeable. This contradicts how similar concepts (e.g. RabbitMQ, Kafka) behave elsewhere: in-process buses are synchronous and transactional while brokers are async with eventual consistency. The common_mistakes reinforce this: lost events on crash, uncaught exceptions rolling back transactions, and synchronous slow operations blocking requests are all consequences of this fundamental confusion.
Also Known As
TL;DR
Explanation
In-process event bus: events dispatched and handled synchronously within a single PHP request. Useful for domain event handling where all subscribers run in the same process. PHP implementations: Symfony EventDispatcher, Laravel Event/Listener, league/event. Message broker bus: events serialised and sent to RabbitMQ/Kafka/SQS, consumed by separate worker processes asynchronously. Hybrid: raise in-process domain events, then publish integration events to the broker via the Outbox Pattern. The choice depends on: consistency requirements, cross-service communication needs, and latency tolerance.
Common Misconception
Why It Matters
Common Mistakes
- In-process event bus for cross-service communication — events are lost if the process crashes.
- No error handling in event listeners — uncaught exceptions in listeners can roll back the main transaction.
- Synchronous slow operations in event listeners — database queries and HTTP calls block the request.
- Not using the Outbox Pattern for guaranteed delivery to a message broker.
Code Examples
// In-process listener doing slow work synchronously:
class OrderPlacedListener {
public function handle(OrderPlaced $event): void {
$this->emailService->sendConfirmation($event->order); // Slow SMTP call
$this->smsService->send($event->order); // External HTTP call
$this->analyticsService->track($event->order); // Another HTTP call
// Checkout response delayed by all three operations
}
}
// Separate concerns: in-process vs async:
// In-process: fast, transactional operations only
class OrderPlacedListener {
public function handle(OrderPlaced $event): void {
// Fast — just queue jobs for async processing:
SendConfirmationEmail::dispatch($event->orderId)->onQueue('notifications');
UpdateInventory::dispatch($event->orderId)->onQueue('inventory');
// Checkout completes immediately
}
}
// Async queue workers handle the slow operations independently