Failure Model¶
Advanced Topic
This page describes the framework's behavior under error conditions. Understanding this is critical for building resilient production systems.
Nalix is designed with a "Safe-by-Default" mindset. Errors in specific requests or connections are isolated to prevent them from affecting the overall stability of the server.
Source Mapping¶
src/Nalix.Abstractions/Networking/IConnectionErrorTracked.cssrc/Nalix.Runtime/Dispatching/PacketDispatchChannel.cssrc/Nalix.Runtime/Dispatching/PacketDispatcherBase.cssrc/Nalix.Runtime/Internal/Routing/DispatchChannel.cs
1. Fault Isolation¶
Nalix enforces strict isolation for all user-provided code (handlers, middlewares, and protocols).
- Handler Exceptions: If a handler throws an unhandled exception, it is caught by the
PacketDispatcherBase. The request is aborted, but the worker thread remains healthy and continues processing the next packet in the queue. - Pipeline Faults: Exceptions within the middleware pipeline are handled similarly. If a middleware fails, the rest of the pipeline is skipped for that specific packet.
Observable Behavior 1¶
- Logging: An
Errorlevel log is emitted via the configuredILogger. - Metrics: The
IConnection.ErrorCount(viaIConnectionErrorTracked) is atomically incremented viaconnection.IncrementErrorCount(). You can monitor this to identify abusive or malfunctioning clients. - Client Signaling: The server attempts to send a
Directivepacket withControlType.FAILandReason = INTERNAL_ERRORto the client.
2. Deserialization Grace¶
Malformed incoming data is intercepted at the earliest possible stage to protect the runtime.
- OpCode Mismatch: If the server receives an opcode that is not registered in the
IPacketRegistry, the frame is discarded. - Binary Corruption: If deserialization fails (e.g., bit flipped or missing field), a
SerializationFailureExceptionis caught internally.
Observable Behavior 2¶
- Diagnostics: A
Warningis logged indicating the unknown or malformed opcode. - Client Signaling: The client receives a
DirectivewithReason = REQUEST_INVALID.
3. Lifecycle Aborts (Timeouts & Disconnects)¶
Nalix uses CancellationToken propagation to ensure that resources are not held by abandoned requests.
- Client Disconnect: If a client drops the connection, the
IConnectionstate is marked inactive. ThePacketDispatchChannelautomatically drains the pending packet queue for that connection and cancels any currently executing handlers via theirPacketContext.CancellationToken. - Execution Timeouts: If a
TimeoutMiddlewareis present, it will cancel the request's token after the specified duration.
Implementation Detail
DispatchChannel.cs listens to the ConnectionUnregistered event from the IConnectionHub to trigger immediate cleanup of per-connection queues.
4. Resource Discipline¶
Regardless of whether a request succeeds or fails, Nalix guarantees consistent resource cleanup.
- Buffer Disposal: Every
BufferLease(raw byte frame) is disposed via atry-finallyblock in the dispatch loop. This prevents memory leaks in theBufferPoolManager. - Context Recycling:
PacketContextobjects are recycled to their internal pools after handler execution, regardless of the outcome.
5. Summary of Effects¶
| Event | Effect on Server | Effect on Client | Visibility |
|---|---|---|---|
| Handler Exception | Worker continues; error count ++ | Receives FAIL directive | ILogger (Error) |
| Malformed Packet | Packet discarded; error count ++ | Receives INVALID directive | ILogger (Warning) |
| Disconnect | Queue drained; handlers cancelled | Connection closed | IConnectionHub event |
| Serialization Fail | Frame discarded; error count ++ | Receives INVALID directive | ILogger (Error) |
Related Source Code¶
src/Nalix.Abstractions/Networking/IConnectionErrorTracked.cs— TheErrorCountcontract.src/Nalix.Runtime/Dispatching/PacketDispatchChannel.cs— Try-catch blocks inProcessOneAsync.src/Nalix.Runtime/Dispatching/PacketDispatcherBase.cs— Try-catch around handler execution.