blackbull.server¶
blackbull.server
¶
BlackBull's server. Construct Server/ASGIServer directly to embed it in an existing event loop or bind before forking.
Server
¶
An asyncio socket server that dispatches each connection through the
app's ProtocolRegistry.
The shared HTTP listener detects HTTP/1.1 vs HTTP/2 (and upgrades to
WebSocket); port-bound non-ASGI protocols registered via
BlackBull.raw_handler get their own listening socket.
When ssl_context or certfile is set, the HTTP listener runs as HTTPS.
ASGIServer is an alias of this class.
certfile
property
writable
¶
The TLS certificate path, or None.
Assigning a path that is not a file raises FileNotFoundError there
and then, rather than at handshake time.
keyfile
property
writable
¶
The TLS private-key path, or None.
Assigning a path that is not a file raises FileNotFoundError there
and then, rather than at handshake time.
ssl_context
property
writable
¶
The context a listener built from certfile/keyfile uses.
Assigning it re-points every bound listener that was carrying the
previous one — which is what makes configuring mTLS after
open_socket() work, and what keeps bound_listeners honest about
what is actually being served. A listener the caller stated carries
its own context and is left alone, because identity is the difference
between "the server's" and "its own".
configure_mtls(ca_cert)
¶
Require a client certificate signed by ca_cert.
TLS must already be configured; on a plaintext server this raises
RuntimeError rather than silently serving without mTLS.
connection_protocol_factory(bound_binding=None)
¶
One buffered protocol per accept; _AcceptGate serves it.
run(port=80)
async
¶
Run an asyncio socket server with the setting in this object.
shutdown()
async
¶
Drive the ASGI lifespan shutdown handshake.
Raises RuntimeError if startup() was never called. After a
failed startup() it cleans up quietly, so try/finally is safe.
startup()
async
¶
Drive the ASGI lifespan startup handshake.
Launches the app's lifespan task, delivers 'lifespan.startup', and waits for 'lifespan.startup.complete'. Raises RuntimeError on 'lifespan.startup.failed'. Stores the context manager so that shutdown() can deliver 'lifespan.shutdown' to the same task.
stop(drain_timeout=8.0)
async
¶
Stop accepting, then let the connections already being served finish.
Nothing in flight is cancelled until drain_timeout less
min(0.5, drain_timeout / 2); then every connection left is aborted,
its unsent output discarded, and its task cancelled, within the
deadline. Keep the budget inside
MultiWorkerServer.shutdown_timeout so the drain ends here and not
in a SIGKILL.