blackbull.server.multiworker¶
blackbull.server.multiworker
¶
Multi-worker master process for BlackBull.
Uses a pre-fork model
- The master binds sockets once (via ASGIServer.open_socket).
- N worker processes are forked; each inherits the socket file descriptors.
- The master monitors workers in a synchronous loop and respawns any that crash.
- On SIGTERM or SIGINT the master sends SIGTERM to all workers, waits up to shutdown_timeout seconds, then SIGKILLs any that are still alive.
When reload=True the master additionally runs a file watcher; on any
matching change it SIGTERMs the workers, marks the listening sockets
inheritable, and os.execvp\ s itself with the original argv — the
fresh process adopts the inherited fds and re-forks workers from the
new code. See :mod:blackbull.server.reload.
The worker entry point is :func:blackbull.server.worker.run_worker.
Each worker runs its own asyncio event loop and its own ASGI lifespan cycle.
Usage::
from blackbull.server.multiworker import MultiWorkerServer
server = MultiWorkerServer(app, raw_sockets, ssl_context, workers=4)
server.run() # blocks until SIGTERM / SIGINT
MultiWorkerServer
¶
Spawns and supervises N worker processes.
Parameters¶
app:
ASGI application callable.
raw_sockets:
Pre-bound sockets that every worker will inherit.
ssl_context:
TLS context, or None for plain HTTP.
workers:
Number of worker processes to maintain.
max_connections:
Per-worker connection limit forwarded to :class:ASGIServer.
shutdown_timeout:
Seconds to wait for graceful shutdown before sending SIGKILL.
run()
¶
Spawn workers and block until a shutdown signal is received.
When reload is enabled the master also runs a file watcher and
re-execs itself on any matching change — see
:mod:blackbull.server.reload.