Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Swerve Laravel Package

phasync/swerve

An asynchronous HTTP client for PHP built on phasync. Swerve offers a clean, fiber-based API for non-blocking requests, making it easy to perform efficient concurrent I/O without extensions or complex event-loop code.

View on GitHub
Deep Wiki
Context7

Getting Started

SWERVE is an application server for PHP built on top of the phasync fiber runtime. Instead of a per-request PHP-FPM lifecycle, you boot a long-running worker process that accepts connections and serves requests cooperatively via fibers. Treat it as experimental infrastructure: the repo is not widely adopted (14 stars), so pin the exact version and read the source before committing.

Prerequisites

  • PHP 8.1+ (fibers are required).
  • Composer.
  • Verify the phasync extension/dependency requirements in the repo's composer.json; the async runtime often needs specific INI settings and may pull in optional extensions.

Minimal steps

  1. composer require phasync/swerve phasync/phasync
  2. Clone/read the repository's examples/ and bin/ directories first — with a package this small, the examples are the documentation.
  3. Identify the bootstrap entry point (typically a server.php or bin/swerve style script). Run it directly with php server.php and confirm it binds a port.
  4. Point curl at the bound port before touching any framework integration.

First use case A minimal JSON endpoint is the right smoke test:

<?php
require __DIR__ . '/vendor/autoload.php';

// Pseudocode — match the actual bootstrap API in the repo.
$server = new Swerve\Server('0.0.0.0:8080');

$server->on('request', function ($request, $response) {
    $response->header('Content-Type', 'application/json');
    $response->write(json_encode(['ok' => true, 'pid' => getmypid()]));
});

$server->run();

If that returns {"ok":true} and the PID stays stable across requests, the process model is working. Then measure concurrency with ab/wrk before adding application logic — the whole value proposition is concurrent request handling.

Implementation Patterns

Request lifecycle and middleware SWERVE is a server, not a full framework. Expect to bring your own router (FastRoute, Symfony Routing) and PSR-7/PSR-15 middleware stack. The clean pattern is a single request handler that delegates into your existing framework kernel:

$server->on('request', function ($req, $res) use ($kernel) {
    $psrRequest  = /* adapt SWERVE request to PSR-7 */;
    $psrResponse = $kernel->handle($psrRequest);
    /* copy status, headers, body onto $res */
});

Keeping the adapter thin means you can swap servers later without rewriting handlers.

Async I/O is the point Inside a handler, every blocking call serializes the worker. Wrap I/O in phasync primitives:

$server->on('request', function ($req, $res) {
    $user   = await(fetchUser($req->query('id')));   // non-blocking DB/HTTP
    $orders = await(fetchOrders($user->id));
    $res->write(json_encode(['user' => $user, 'orders' => $orders]));
});

If your ORM or HTTP client is synchronous (PDO, Guzzle sync, file I/O on slow disks), you gain little. Prefer clients with async drivers, or run blocking work on a small pool of dedicated workers.

Concurrency within a request Use phasync channels/futures to fan out and join:

$results = await(phasync\all([
    fetchA(), fetchB(), fetchC(),
]));

This is the biggest day-to-day win: parallel downstream calls with a single PHP worker.

Long-lived state Because the process persists, you can cache hot configuration, compiled routes, and connection pools at boot. Do initialization once outside the request handler. Never store per-request data on the server object or in globals.

Graceful shutdown Handle SIGTERM/SIGINT, stop accepting new connections, drain in-flight fibers, close pools, then exit. Container orchestrators will send SIGTERM and kill after a grace period — an unhandled signal means dropped requests on every deploy.

Deployment shape Run SWERVE behind nginx (or a load balancer) as a reverse proxy. Bind to 127.0.0.1 or a private interface; the server does not replace TLS termination. Run N workers under a supervisor (systemd, supervisord, or the package's own worker flag if present) and size N to CPU cores.

Testing Unit-test handlers by invoking the request callback directly with fake request/response objects. Integration-test with real curl against a booted server on an ephemeral port. Add a concurrency test (parallel requests asserting independent responses) to catch shared-state bugs.

Gotchas and Tips

Global and static state is now dangerous. Anything you cached in $_SERVER, $_GET, or a static singleton in the FPM world will leak across requests. Audit for global, static $x, and framework singletons that assume a fresh process. Reset per-request container state explicitly.

Memory leaks compound. A 1 KB leak per request is invisible under FPM and fatal after 100k requests. Log memory_get_usage() periodically, set a max-request counter that recycles the worker, and load-test with --max-requests style recycling enabled.

One blocking call stalls the whole worker. A forgotten sleep(), a sync file_get_contents on a slow mount, or a synchronous PDO query under load will present as "the server hangs." Instrument handler duration; anything over a few milliseconds that isn't awaited is a suspect. This is the single most common failure mode for fiber-based servers.

Timeouts are your responsibility. There is no FPM max_execution_time safety net in the same way. Set explicit timeouts on every outbound call and on the request handler itself, or a stuck downstream dependency will exhaust your worker pool.

Error handling must be explicit. An uncaught exception inside a fiber can tear down the worker rather than return a 500. Wrap the top-level handler in try/catch, log with a correlation ID, and always emit a response — even on failure. Verify the server's behavior on uncaught exceptions during your smoke test.

Config quirks. Read the bootstrap source for defaults: worker count, socket backlog, keep-alive, body size limits, and timeout settings often live in plain PHP arrays rather than a published config file. Copy defaults into your own config so upgrades don't silently change behavior.

Extension points to watch for. Request/response hooks, connection events (open, close), and worker lifecycle callbacks are where you'll wire metrics, tracing, and health checks. Prefer these over monkey-patching handlers.

Version pinning and API churn. Given the low adoption and a release date far in the future relative to typical package cadence, expect breaking changes. Pin to an exact tag, commit your composer.lock, and keep the server adapter isolated in one file so a rewrite is contained.

Debugging approach. Log the PID and a request ID on every request — you need to know which worker handled what. When something hangs, attach gdb/strace or dump fiber stacks if the runtime exposes them; otherwise bisect by disabling middleware. Reproduce under concurrent load, not with a single curl, since most bugs here are concurrency bugs.

Be honest about the maturity trade-off. Evaluate SWERVE against RoadRunner, Swoole, FrankenPHP, and ReactPHP. The differentiator is the native fiber model and PHP-only stack (no extension required, if that holds), not ecosystem breadth. Use it for internal services where you control the clients and can tolerate API churn; avoid it for anything requiring a stable public contract until the package has more adoption.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core