spiral/roadrunner-worker
The common codebase for all RoadRunner binary workers—the high-performance PHP application server, load balancer, and process manager that replaces Nginx+FPM with PSR-7/PSR-17 compatible HTTP and HTTP/2 support.
composer require roadrunner/worker (as of v3.8.0, the package was renamed from spiral/roadrunner-worker; the old name was retired). Current patch release: v3.8.2Spiral\RoadRunner\Worker and implementing a request loop (the namespace is unchanged by the rename):
use Spiral\RoadRunner\Worker;
require __DIR__ . '/vendor/autoload.php';
$worker = new Worker();
while ($req = $worker->waitRequest()) {
try {
$payload = json_decode($req->getPayload(), true);
$response = ['result' => 'Handled: ' . ($payload['action'] ?? 'unknown')];
$worker->respond($response);
} catch (\Throwable $e) {
$worker->error((string)$e);
}
}
.rr.yaml to point to your worker script (exec: php worker.php)./rr servespiral/roadrunner-worker with roadrunner/worker in composer.json, run composer update roadrunner/worker, and grep for the old name in docs, Dockerfiles, and CI caches. composer why spiral/roadrunner-worker quickly reveals transitive dependents (Laravel Octane, spiral/roadrunner-laravel, nyholm/psr7-server bridges) that may pin the legacy name.roadrunner/roadrunner installed alongside the worker: since v3.8.2, the worker detects the RoadRunner version through the roadrunner/roadrunner dependency rather than relying on a locally hardcoded constant. If your project prunes that package (e.g. composer remove --dev or a --no-dev build that drops it), version detection degrades. Leave it in require and let it resolve transitively via Octane / spiral/roadrunner-laravel.QueueWorker, HttpWorker) by checking request headers (e.g., rr-worker-type) or payload structure$container = buildContainer(); // expensive setup once
while ($req = $worker->waitRequest()) {
$handler = $container->get(SomeHandler::class);
$handler->handle($req);
}
Spiral\RoadRunner\PSR7Client) and pass to Symfony Messenger or Laravel Queue for unified processing$worker->isStopRequested() in the loop to respond to RoadRunner's /stop signal and flush pending work before exitingrespond() for observability#[\Override]. When you subclass Worker or related classes, add #[\Override] to the methods you override — PHP will now fail fast at class-load if a parent signature changes or a method is removed in a future release. This is a cheap upgrade safety net worth adopting in your own workers too.composer require spiral/roadrunner-worker in docs or scripts must become roadrunner/worker. Old lock files will keep resolving the legacy name until you update; CI that installs from a stale composer.lock may silently stay on v3.7.x. Verify with composer show roadrunner/worker and composer show | grep roadrunner.roadrunner/roadrunner package instead of any hardcoded/duplicated constant. Practical impact:
Spiral\RoadRunner\Version::VERSION in your own tests, that value now tracks the installed roadrunner/roadrunner release — pin it in composer.json if you need a deterministic assertion.rr binary in manually but skip roadrunner/roadrunner will report no/incorrect version. Either install the package or set RR_VERSION explicitly as an override.roadrunner/roadrunner and the rr binary together; a stale binary against a freshly resolved package is the most common source of phantom mismatches.try/catch and use $worker->error($msg) for non-fatal issuesPsr\Http\Message\ServerRequestInterface (via spiral/roadrunner-http) or raw strings (via spiral/roadrunner-queue). Decode appropriately using $req->getPayload() or cast to PSR if availableRR_DEBUG=1 and check RoadRunner logs (./rr serve -d) to see worker communication. For version issues specifically, dump composer show roadrunner/roadrunner next to ./rr --version — the two must agree.Spiral\RoadRunner\Environment to externalize config; override Worker methods like respond() for custom serialization (e.g., JSON to MessagePack) — and mark them #[\Override]roadrunner/worker v3+ requires RoadRunner v2. From v3.8.2 onward the worker derives the expected version from the installed roadrunner/roadrunner package, so keep package and binary in lockstep; use the RR_VERSION env var only as a manual override when the package isn't present. The v3.8.0 rename and this detection change do not alter the RoadRunner binary compatibility contract.composer update roadrunner/worker inside the 3.8.x line requires no code edits — just re-run your worker smoke test and confirm the logged version matches the binary.How can I help you explore Laravel packages today?