Skip to content

[API Proposal]: Option to limit SseParser's internal buffer size #129168

Description

@MihaZupan

Background and motivation

SSE is a line-delimited protocol, so SseParser must internally buffer received content until it reaches said new line. It then hands the user a contiguous buffer as a ReadOnlySpan<byte> argument to the SseItemParser<T>.

There's no way to change what the limit for the amount of buffered data is, so it currently defaults to ~1 GB.
The proposed API allows you to change the limit, which also gives us the option to make breaking changes in the future to reduce it to more reasonable values if we so choose.

API Proposal

namespace System.Net.ServerSentEvents;

+public sealed class SseParserOptions<T>
+{
+    public SseParserOptions(SseItemParser<T> itemParser);

+    public SseItemParser<T> ItemParser { get; }
+    public int MaxBufferSize { get; set; } = SomeInternalConst;
+}

public static partial class SseParser
{
    public static SseParser<string> Create(Stream sseStream);
    public static SseParser<T> Create<T>(Stream sseStream, SseItemParser<T> itemParser);
+   public static SseParser<T> Create<T>(Stream sseStream, SseParserOptions<T> options);
}

API Usage

using Stream responseStream = await httpClient.GetStreamAsync("https://contoso.com/sse", cancellationToken);

-SseParser<string> parser = SseParser.Create(responseStream, (_, bytes) => Encoding.UTF8.GetString(bytes));
+SseParser<string> parser = SseParser.Create(responseStream, new SseParserOptions<string>((_, bytes) => Encoding.UTF8.GetString(bytes))
+{
+    MaxBufferSize = 1024 * 1024 // 1 MB
+});

await foreach (SseItem<string> item in parser.EnumerateAsync(cancellationToken))
{
    Console.WriteLine(item.Data);
}

Alternative Designs

We could add an overload with just the new argument and expose options in the future if needed.

namespace System.Net.ServerSentEvents;

public static partial class SseParser
{
    public static SseParser<string> Create(Stream sseStream);
    public static SseParser<T> Create<T>(Stream sseStream, SseItemParser<T> itemParser);
+   public static SseParser<T> Create<T>(Stream sseStream, SseItemParser<T> itemParser, int maxBufferSize);
}

Risks

🤷‍♂️

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions