sabre/event
Lightweight PHP 8.2+ library for event-driven development: EventEmitter, promises, an event loop, and coroutines. Used to build reactive, non-blocking apps and services. Full docs at sabre.io/event.
EventEmitter and Promise implementations align with Laravel’s event system but extend it with asynchronous primitives (e.g., coroutines, event loop). Ideal for non-HTTP contexts where Laravel’s synchronous Bus/Events fall short (e.g., WebSocket servers, CLI async workflows).Bus uses Promises under the hood, but Sabre/Event’s event loop adds non-blocking I/O capabilities.yield for async waits), useful for high-throughput tasks (e.g., API polling, batch processing) where synchronous loops would bottleneck.*), useful for plugin systems or modular architectures.EventLoop can block PHP’s SAPI (e.g., Apache/Nginx). Use only in CLI/Artisan commands or custom workers.EventLoop::run() to process jobs without Redis).Emitter instances as singletons for global event propagation.| Risk Area | Assessment | Mitigation Strategy |
|---|---|---|
| Event Loop Blocking | Can freeze HTTP requests if used in SAPI context. | Isolate usage: Restrict to CLI/Artisan. Use Laravel’s queue:work for HTTP async tasks. |
| PHP 8.2 Dependency | Breaks compatibility with older Laravel versions (e.g., <9.x). | Phase migration: Upgrade PHP/Laravel incrementally. Use v6.0.x (PHP 7.4–8.1) as a stopgap for legacy systems. |
| Learning Curve | Coroutines/Promises require async programming knowledge. | Training: Document patterns (e.g., coroutine + yield). Provide examples for common use cases (e.g., WebSocket handlers, batch jobs). |
| Lack of Laravel Binds | No native integration with Laravel’s Bus/Events. |
Wrapper Layer: Create a facade to bridge Sabre/Event with Laravel’s Event class (e.g., SabreEvent::emit()). |
| Performance Overhead | Event loop adds scheduling overhead for simple tasks. | Benchmark: Compare with synchronous loops/queues. Use only for I/O-bound tasks (e.g., HTTP requests, file operations). |
Bus/Events? (Performance? Async primitives?)v6.0.x (PHP 7.4–8.1) a viable alternative?EventLoop run in background processes (e.g., supervisor) or blocking HTTP?App\Exceptions\Handler may need extension.)| Component | Fit Level | Notes |
|---|---|---|
| Laravel HTTP Apps | ❌ Poor | EventLoop blocks SAPI. Use only for non-HTTP async (e.g., Artisan commands). |
| Laravel Queues | ✅ Good | Replace synchronous job processing with EventLoop-driven workers (e.g., EventLoop::run() for batch jobs). |
| CLI/Artisan | ✅ Excellent | Ideal for async CLI tools, WebSocket servers, or background workers. |
| Plugin Systems | ✅ Excellent | Wildcard listeners (*) enable dynamic event routing. |
| Microservices | ✅ Good | Lightweight event-driven communication between PHP services (e.g., Emitter for inter-service events). |
| Real-Time APIs | ✅ Excellent | Event Loop + Coroutines for non-blocking WebSocket/HTTP streaming. |
Assess PHP/Laravel Version:
sabre/event:^6.1 (latest).sabre/event:^6.0 (backported fixes).Isolate Integration:
composer.json:
composer require sabre/event "^6.1" --dev # or "^6.0" for legacy
Emitter in a service provider:
$this->app->singleton(Sabre\Event\EmitterInterface::class, function () {
return new Sabre\Event\Emitter();
});
Bridge Laravel Events (Optional):
class SabreEventFacade {
public static function emit(string $event, $data = null) {
$emitter = app(Sabre\Event\EmitterInterface::class);
$emitter->emit($event, $data);
}
}
Replace Synchronous Logic:
$result = someBlockingFunction();
$generator = function () {
$result = yield Sabre\Event\coroutine(function () {
return someBlockingFunction();
});
return $result;
};
$result = Sabre\Event\EventLoop::run($generator());
Adapt Promises:
Bus Promises with Sabre/Event’s:
use Sabre\Event\Promise;
$promise = Promise\resolve('data')
->then(function ($data) {
return process($data);
})
->otherwise(function (Throwable $e) {
log($e);
});
Event Loop for Workers:
artisan sabre:worker):
// In a custom Artisan command
Sabre\Event\EventLoop::run(function () {
$emitter = app(Sabre\Event\EmitterInterface::class);
$emitter->on('task', function ($data) {
// Process async
});
});
| Laravel Feature | Sabre/Event Compatibility | Notes |
|---|---|---|
| Events | ✅ Partial | Use facade to bridge Laravel Event class to Sabre Emitter. |
| Queues | ✅ Partial | Replace synchronous job processing with EventLoop. Not a drop-in replacement for queue:work. |
| Bus/Promises | ✅ High | Sabre’s Promise API is ECMAScript 6 compliant; interoperable with Laravel’s `Bus |
How can I help you explore Laravel packages today?