Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ public IAsyncEnumerable<OperationResult> ReadAsResultStreamAsync(CancellationTok

if (contentType?.MediaType.EqualsOrdinal(ContentType.EventStream) ?? false)
{
return new SseReader(_message);
return new SseReader(_message, cancellationToken);
}
Comment on lines 166 to 169
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ReadAsResultStreamAsync now forwards the provided cancellationToken into SseReader, but SseReader currently treats a canceled PipeReader read as a normal end of stream (yield break) rather than propagating an OperationCanceledException. That makes cancellation behavior inconsistent with the non-SSE paths (which throw when the token is canceled) and makes it hard for callers to distinguish cancellation vs completion. Consider updating the SSE reader to throw when cancellation is requested (e.g., when the read is canceled) so this token has the expected observable effect.

Copilot uses AI. Check for mistakes.

// The server supports the newer graphql-response+json media type and users are free
Expand Down
11 changes: 8 additions & 3 deletions src/HotChocolate/AspNetCore/src/Transport.Http/Sse/SseReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

namespace HotChocolate.Transport.Http;

internal class SseReader(HttpResponseMessage message) : IAsyncEnumerable<OperationResult>
internal class SseReader(
HttpResponseMessage message,
CancellationToken requestCancellationToken = default) : IAsyncEnumerable<OperationResult>
{
private static readonly StreamPipeReaderOptions s_options = new(
pool: MemoryPool<byte>.Shared,
Expand All @@ -18,8 +20,11 @@ internal class SseReader(HttpResponseMessage message) : IAsyncEnumerable<Operati
public async IAsyncEnumerator<OperationResult> GetAsyncEnumerator(
CancellationToken cancellationToken = default)
{
using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
await using var stream = await message.Content.ReadAsStreamAsync(cts.Token);
using var cts = CancellationTokenSource.CreateLinkedTokenSource(
requestCancellationToken,
cancellationToken);
await using var stream =
await message.Content.ReadAsStreamAsync(cts.Token).ConfigureAwait(false);
using var eventBuffer = new PooledArrayWriter();
var reader = PipeReader.Create(stream, s_options);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ mutation CreateReviewForEpisode(
var canceled = false;
try
{
await foreach (var result in subscriptionResponse.ReadAsResultStreamAsync().WithCancellation(cts.Token))
await foreach (var result in subscriptionResponse.ReadAsResultStreamAsync(cts.Token))
{
result.MatchInlineSnapshot(
"""
Expand Down
Loading