Packet Context¶
PacketContext<TPacket> is the concrete pooled runtime object that represents a single packet execution within Nalix. Handler and middleware code usually consume it through IPacketContext<TPacket>, while the runtime keeps reusing the same concrete object shape underneath.
Source Mapping¶
src/Nalix.Runtime/Dispatching/PacketContext.cs
Context Lifecycle & Pooling¶
To achieve ultra-low GC pressure, PacketContext<TPacket> instances are heavily pooled through ObjectPoolManager. The following diagram illustrates the lifecycle of a context object from the pool to execution and back.
stateDiagram-v2
[*] --> Pooled
Pooled --> InUse: 1. Rent (ObjectPoolManager)
InUse --> Initialized: 2. Initialize(Packet, Conn, Meta)
state Execution {
Initialized --> Middleware
Middleware --> Handler
Handler --> Outbound
}
Execution --> Returned: 3. Return()
Returned --> Pooled: 4. ResetForPool()
Why pooling is essential¶
In a system processing tens of thousands of packets per second, creating a new context object for every request would overwhelm the Garbage Collector. Nalix uses ObjectPoolManager to:
- Minimize Gen0 Allocations: The object remains in memory and is reused millions of times.
- Pre-allocation: Contexts are pre-allocated during startup based on the
PoolingOptions.PacketContextPreallocatesetting. - Reference Cleanup: Strict Reset/Return protocols ensure that application data from one request doesn't "leak" into the next request.
Core Interface: IPacketContext<TPacket>¶
The context provides several critical properties for handler developers:
| Property | Description |
|---|---|
Packet |
The strongly-typed deserialized packet payload. |
Connection |
The source IConnection including IP, identity, and custom attributes. |
Sender |
A sender initialized for this specific context and used for reply paths or manual sends. |
Attributes |
Read-only metadata resolved during dispatch (Ops, permissions). |
CancellationToken |
A token linked to the dispatch loop or connection shutdown. |
IsReliable |
true when the packet was received over a reliable transport (TCP). |
SkipOutbound |
When true, outbound middleware is skipped for this context. |
Memory Safety Rules¶
- Handoff Exclusion: Once a handler completes, the context is automatically returned to the pool. Do not store a reference to the context outside the handler scope.
- Sender Usage: Use
context.Senderwhen replying manually. The sender is rebound duringInitialize(...)so it follows the current connection and transport semantics for that execution. - Manual Return: In advanced scenarios (like bypass dispatching), call
.Return()or.Dispose()exactly once when you are done. The current implementation makes the transition idempotent, but the ownership contract is still single-return.