Installation:
composer require hyperf/engine
Ensure your project uses PHP 8.0+ and Swoole 4.5+ (or later, as per compatibility notes).
First Use Case: Launch a coroutine task in a Laravel command or route handler:
use Hyperf\Engine\Coroutine;
Coroutine::create(function () {
// Non-blocking I/O operations (e.g., HTTP requests, DB queries)
$response = file_get_contents('https://api.example.com/data');
return $response;
});
Key Entry Points:
Coroutine::create(): Spawn a new coroutine.Coroutine::run(): Run a coroutine immediately (blocks current thread).Coroutine::sleep(): Non-blocking sleep (microseconds).Coroutine::yield(): Pause/resume coroutines manually.Where to Look First:
hyperf/engine tests for usage examples.Non-Blocking HTTP Requests:
Coroutine::create(function () {
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.example.com');
// Process response...
});
Guzzle with Swoole’s coroutine client or curl_multi for async I/O.Database Queries:
Coroutine::create(function () {
$results = DB::select('SELECT * FROM large_table');
// Process results...
});
doctrine/dbal or illuminate/database (ensure PDO drivers support coroutines).Event Loop Integration:
Coroutine::run(function () {
while (true) {
$data = Coroutine::yield(); // Pause until data is available
// Handle $data...
}
});
Worker Pooling:
$tasks = [];
foreach ($items as $item) {
$tasks[] = Coroutine::create(function () use ($item) {
return processItem($item);
});
}
Coroutine::all($tasks); // Wait for all to complete
Middleware for Async Processing:
public function handle($request, Closure $next) {
Coroutine::create(function () use ($request) {
$response = $next($request);
// Async post-processing...
});
return $next($request); // Sync path
}
Queue Workers:
// In a Laravel command
Coroutine::create(function () {
while ($job = $this->queue->pop()) {
$job->handle();
}
});
Real-Time Features:
laravel-websockets or pusher-php-server for WebSocket coroutines:
Coroutine::create(function () {
$socket = new \Swoole\WebSocket\Server(...);
while (true) {
$socket->recv(); // Non-blocking
}
});
sleep(), file_get_contents() (sync), or synchronous DB calls inside coroutines.try-catch:
try {
Coroutine::create(fn() => riskyOperation());
} catch (\Throwable $e) {
Coroutine::sleep(1000); // Backoff
}
$service = app()->make(CoroutineService::class);
Coroutine::create(fn() => $service->execute());
Global State Corruption:
Coroutine::getContext()).Blocking the Event Loop:
str_replace with large strings) can stall coroutines.Coroutine::yield() to release the event loop.Resource Leaks:
finally blocks or context managers:
Coroutine::create(function () {
$db = DB::connection();
try {
$db->select(...);
} finally {
$db->disconnect();
}
});
Laravel’s Sync Defaults:
DB, Cache, and Queue are synchronous by default. Use coroutine-compatible alternatives:
doctrine/dbal with PDO_SQLSRV or hyperf/db-connection.swoole/cache or predis/predis (Redis).hyperf/queue or spatie/laravel-async.Timeouts:
Coroutine::sleep() or Swoole\Timer:
$timer = Coroutine::create(function () {
Coroutine::sleep(5000); // 5s timeout
throw new \RuntimeException("Operation timed out");
});
Stack Traces:
Coroutine::getContext() to inspect state:
error_log(Coroutine::getContext());
\Swoole\Coroutine::set(['trace_enable' => true]);
Logging:
\Log::debug('Coroutine ID: ' . Coroutine::id(), ['data' => $data]);
Common Errors:
go() or Coroutine::create() is used (not raw Swoole\Coroutine).Swoole Version Mismatches:
hyperf/engine requires Swoole 4.5+. Check compatibility in composer.json:
"require": {
"ext-swoole": "^4.5 || ^5.0"
}
hyperf/engine v2.12.1+.PHP Extensions:
opcache.jit_buffer if coroutines behave erratically (JIT can interfere with coroutine context).Laravel Service Providers:
AppServiceProvider:
$this->app->bind(CoroutineService::class, function () {
return new CoroutineService(\Swoole\Coroutine::getuid());
});
Custom Coroutine Classes:
class AsyncTask extends \Hyperf\Engine\Coroutine
{
public function __construct() {
parent::__construct();
$this->set(['hook_flags' => SWOOLE_HOOK_ALL]);
}
}
Hooks for Low-Level Control:
\Swoole\Coroutine::addHook(SWOOLE_HOOK_ALL, function ($hookType) {
\Log::debug("Coroutine hook triggered: {$hookType}");
});
Integration with Hyperf:
hyperf/engine directly for shared coroutine logic:
use Hyperf\Engine\Coroutine as EngineCoroutine;
// Replace Laravel's async calls with EngineCoroutine.
How can I help you explore Laravel packages today?