Skip to content

WebSocket receive path copies every frame before deserialization #32

@nficano

Description

@nficano

WebSocketTransport.ReceiveAsync rents a buffer, writes each received frame into a new MemoryStream, then calls ms.ToArray() before deserializing. For the common case where a complete envelope fits in one receive buffer, this allocates both the MemoryStream backing storage and a second array copy for every message. ARCP transports can carry high-volume event streams, so this avoidable allocation path can become noticeable under load.

The relevant locations are src/Arcp.Core/Transport/WebSocketTransport.cs:48, src/Arcp.Core/Transport/WebSocketTransport.cs:53, src/Arcp.Core/Transport/WebSocketTransport.cs:63, and src/Arcp.Core/Transport/WebSocketTransport.cs:72.

Fix prompt: Optimize WebSocketTransport.ReceiveAsync to deserialize directly from the rented buffer when EndOfMessage is true on the first receive, and use a pooled growable buffer such as ArrayBufferWriter<byte> or a reusable pooled stream for fragmented messages. Preserve the existing behavior for close frames and malformed JSON, return rented arrays in all paths, and add allocation-sensitive tests or benchmarks that cover single-frame and fragmented messages.

Metadata

Metadata

Assignees

No one assigned

    Labels

    performancePerformance and allocation improvementsseverity:lowLow severity

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions