Architecture¶
Protocol ownership¶
Keep HTTP/1.1, HTTP/2, WebSocket, gRPC and MQTT wire handling in BlackBull's
Python code. Do not replace it with a third-party protocol state machine.
HPACK uses the pure-Python hpack codec; standard-library C extensions and
optional uvloop do not change protocol ownership.
Multi-protocol, one process¶
All protocols share one runtime. Attach non-HTTP protocols through
app.add_extension(...) and select sockets through
listeners. Protocol dispatch belongs to bindings,
not application routing or a second server runtime.
The server is part of the core: import blackbull loads it, because the
public listener types (Listener, Tcp, Unix, InheritedFd) and raw
bindings are server objects. An app handed to an external ASGI host pays
that import once, never per request.
Actor model¶
Mutable protocol state has one owner. Coordinate concurrent work through messages and explicit lifetime boundaries, not shared locks. MQTT routing and socket output have separate serial inbox owners. HTTP/2 streams share connection-level framing, HPACK and flow control while retaining isolated request work. See Internals and MQTT broker design.
Fault injection¶
Fault servers assemble their own wire bytes. They must not reuse production serializers, because a shared serializer cannot expose its own defects. Use the fault-injection guide for scenarios and differential oracles.
Conformance¶
Use conformance workflows and their artifacts to check a
change. A finite suite establishes its cases, not complete correctness.
Keep measurements and run records under bench/.
What BlackBull defers¶
Before extending the public surface, check Known limitations and the use-case guide.