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

Swoole Bridge Bundle Laravel Package

insidestyles/swoole-bridge-bundle

Symfony bundle that bridges Swoole with your application, enabling high-performance coroutine-based HTTP serving from long-running workers while handling request lifecycle and service resets safely between requests.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony bundle, not a Laravel package. That's the first thing to internalize: there is no service provider, no config/swoole.php, and nothing auto-discovers in a Laravel app. If you're coming from Laravel expecting a swooletw/laravel-swoole-style drop-in, this bundle will not give you that. What it actually gives you is a small, reusable bridge between a Swoole HTTP server and a PHP framework kernel — useful as a reference implementation or as the seed for your own integration, less so as something you composer require and forget.

Minimal steps to evaluate it:

  1. pecl install swoole (or openswoole), enable extension=swoole, and confirm with php -m | grep -i swoole. Check the extension version against the bundle's composer.json constraint — this is a common silent failure.
  2. composer require insidestyles/swoole-bridge-bundle in a Symfony 5/6 application, not a Laravel one.
  3. Register SwooleBridgeBundle in config/bundles.php.
  4. Publish/author the config block (typically swoole_bridge:) for host/port, worker_num, task_worker_num, max_request, and the kernel document root.
  5. Boot the server with the bundled console command (typically swoole:server:start) and hit http://localhost:9501.

Where to look first: read the bundle's DependencyInjection/ and Command/ directories before touching config. The star count is low and the package is thin, so the source is the documentation. Skim the request/response conversion code specifically — that's where the bundle's opinions live and where your integration will need to patch.

First real use case: the honest one is a spike. Stand up the bundle in a scratch Symfony app, proxy your most stateful endpoint through it, and see what leaks between requests. That tells you in an afternoon whether a Swoole bridge is viable for your workload. If your actual target is Laravel, take what you learn from the request/response adapter here and wire it into swooletw/laravel-swoole or your own Octane-style worker instead — you'll get a maintained package and a supported kernel lifecycle.

Implementation Patterns

Long-running kernel, per-worker. The bundle boots a Symfony kernel once per worker and dispatches many requests through it. Everything you know about "container is rebuilt every request" is now false. The pattern that keeps this sane:

  • Reset services between requests, not on boot. Use kernel.reset tags / ServicesResetter if the bundle wires it, and audit every service you own for mutable state.
  • Treat Doctrine's EntityManager as disposable. After a failed flush or a caught ORMException, $em->clear() and re-fetch — do not hold references across requests.
  • Rebuild anything request-scoped (security token, locale, timezone) explicitly at the start of each dispatch.

Request/response conversion is the integration surface. Swoole hands you a raw Swoole\Http\Request; the bundle maps it into a framework Request and maps the returned Response back onto Swoole\Http\Response. In practice you'll extend or override this adapter to handle:

  • File uploads (map Swoole's $request->files into UploadedFile objects, including tmp_name semantics — Swoole's temp files are deleted after the callback, so copy or move them synchronously).
  • Streaming / large responses — Swoole supports chunked writes natively; a naive Response::send() will buffer the whole body in memory.
  • HEAD requests and 304s, which need the response writer to suppress the body while keeping headers.
  • Cookies and headers with duplicate names.

Task workers for anything blocking. If the bundle exposes task_worker_num, use it for mail, image processing, webhooks, and anything else you'd normally shove into a queue but can afford to do in-process. This is the cheapest win the bundle offers — a genuine alternative to a Redis-backed queue for low-volume, latency-tolerant work.

Configuration as code, checked into the repo. The config block should live in config/packages/ and differ per environment:

  • worker_num: ~1–2× CPU cores for I/O-bound, never more than cores for CPU-bound work.
  • max_request: set it. 500–1000 is a reasonable default. This is your memory-leak circuit breaker.
  • Dev environment: 1 worker, and use the bundle's reload capability (Swoole's reload() or a file watcher) so you aren't restarting the process on every edit.

Integration with Messenger / queue consumers. If you're already using Symfony Messenger, the sweet spot is running consumers as Swoole task workers in addition to the HTTP workers, so async work shares the same warm container. The bundle may or may not support this out of the box; if it doesn't, a small custom command that boots the kernel and loops $bus->dispatch() is a few dozen lines.

Middleware over kernel events. If the bundle dispatches through the normal HttpKernel, your existing listeners and middleware work unchanged. Verify this early — if it bypasses the kernel and calls the controller directly, you lose the entire middleware stack and need to reimplement auth, CSRF, and error handling manually.

Gotchas and Tips

Global state is the whole ballgame. $_GET, $_POST, $_SERVER, $_SESSION, $_COOKIE are not reliably populated under Swoole in the way PHP-FPM populates them. Any code that reads superglobals directly — third-party SDKs, older libraries, filter_input() — will misbehave. Grep your dependency tree for superglobal access before committing to this path. This is the single most common reason these bridges fail in production.

header(), setcookie(), and echo do nothing useful. Everything must flow through the returned response object. Framework helpers that assume they can emit headers directly will silently drop them. Test a page that sets a Set-Cookie and a redirect explicitly.

Sessions need a real backend. Even if the bridge shims $_SESSION, Swoole's concurrency model means you should move sessions to Redis or a database rather than file-based storage, and be aware that a single worker handling concurrent requests through coroutines shares process memory. If the bridge is coroutine-based, session writes from two concurrent requests in the same worker can race.

Memory leaks accumulate quietly. PHP-FPM freed everything at process exit; Swoole does not. Watch RSS over an hour of synthetic load. Common offenders: containers holding request objects in log buffers, Doctrine's identity map, static caches in libraries, $GLOBALS writes. max_request masks the symptom — find the leak.

Xdebug is effectively unusable. Coroutines and the Swoole event loop break step debugging. Plan to debug via structured logs (Monolog with a request ID propagated through the adapter) and via swoole's own stats endpoints. Profile with xhprof/tideways if you must.

Graceful shutdown and signal handling. Verify that SIGTERM drains in-flight requests before exiting, and that your deployment story accounts for it. With FPM, a rolling restart is trivial; with a long-running server, you need health checks and a drain period in your orchestrator config or you'll 502 during every deploy.

OPcache and preloading. Enable opcache.enable_cli=1 (or the equivalent for your SAPI), and consider opcache.preload with a preload script that warms the container. Without it, cold worker starts are noticeably slower than you'd expect.

Version pinning. At 31 stars and with zero dependents, treat this as unmaintained. Pin the exact version and vendor the source if you depend on it, or — better — fork the 400 relevant lines into your own bundle where you control the lifecycle. Check the last commit date and the Symfony version in composer.json: if it targets Symfony 4/5, expect friction on 6.4/7.x due to container and event dispatcher signature changes.

Extension points to look for, in priority order: (1) the request→framework-request adapter, since you'll need to customize it first; (2) the server start command, for lifecycle hooks; (3) bundle events for worker start/stop, useful for warming caches and flushing metrics; (4) the DI configuration, for adding task-worker definitions. If the bundle doesn't expose 1 and 3, don't fight it — fork.

The blunt recommendation: evaluate this as a learning artifact, not a dependency. It shows you the shape of a Swoole bridge cleanly, and that's worth the afternoon. For production Symfony, look at symfony/runtime plus a maintained Swoole integration, or FrankenPHP/RoadRunner which solve the same problem with an actively maintained server and a smaller set of semantic surprises. For production Laravel, Laravel Octane with the Swoole or FrankenPHP driver is the supported path and gives you the same performance profile with a maintained reset contract.

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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource