Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CancellationToken support for LoadIntoBufferAsync #103991

Merged
merged 5 commits into from
Jul 8, 2024

Conversation

manandre
Copy link
Contributor

Closes #102659

Copy link

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

Copy link

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Jun 25, 2024
Copy link
Contributor

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

HttpCompletionOption.ResponseHeadersRead);

var cts = new CancellationTokenSource();
cts.Cancel();
Copy link
Member

Choose a reason for hiding this comment

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

If you're not going to check the identity of the token, this can just be new CancellationToken(true). But if we expect the resulting exception to contain this token, then we should also be validating that after the below assert.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tests updated accordingly.

await connection.SendResponseAsync(LoopbackServer.GetHttpResponseHeaders(contentLength: 100));
await Task.Delay(250);
cts.Cancel();
await Task.Delay(500);
Copy link
Member

@stephentoub stephentoub Jun 26, 2024

Choose a reason for hiding this comment

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

Do the delays need to be this long? Might want to mark the test as outerloop if there's no way to shrink them. Even better would be to find a way to make it more deterministic without timeouts / delays.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am not sure but I assume that these delays try to enforce the LoadIntoBuffer task to actively wait on the cancellation token.
For now I have moved it to outerloop, but ideas to make it deterministic are welcome.

Copy link
Member

Choose a reason for hiding this comment

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

A deterministic version would look something like a revert of ef6a5a2.

var observedCancellation = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
var exception = await Assert.ThrowsAsync<TaskCanceledException>(() => task);
observedCancellation.SetResult();
await connection.SendResponseAsync(LoopbackServer.GetHttpResponseHeaders(contentLength: 100));
await Task.Yield();
cts.Cancel();
await observedCancellation.Task.WaitAsync(TestHelper.PassingTestTimeout);

But as written, this test isn't enforcing that the client actually honors the cancellation token before receiving the whole response.
The browser implementation seems to be struggling with this (I had to revert a similar change in #104384 due to test failures - console logs). cc: @pavelsavara

Given that this test is a copy-paste of existing test logic we have in this file, I'd keep it as-is in this PR.

Copy link
Member

Choose a reason for hiding this comment

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

In the browser the server side is played by xharness and driven via WebSocket, that makes it lot slower to react to anything.

It could be probably rewritten in deterministic way, but it could be separate PR if desired.

Copy link
Member

@stephentoub stephentoub left a comment

Choose a reason for hiding this comment

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

Product changes LGTM. Thanks!

Copy link
Member

@MihaZupan MihaZupan left a comment

Choose a reason for hiding this comment

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

Thanks

await connection.SendResponseAsync(LoopbackServer.GetHttpResponseHeaders(contentLength: 100));
await Task.Delay(250);
cts.Cancel();
await Task.Delay(500);
Copy link
Member

Choose a reason for hiding this comment

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

A deterministic version would look something like a revert of ef6a5a2.

var observedCancellation = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
var exception = await Assert.ThrowsAsync<TaskCanceledException>(() => task);
observedCancellation.SetResult();
await connection.SendResponseAsync(LoopbackServer.GetHttpResponseHeaders(contentLength: 100));
await Task.Yield();
cts.Cancel();
await observedCancellation.Task.WaitAsync(TestHelper.PassingTestTimeout);

But as written, this test isn't enforcing that the client actually honors the cancellation token before receiving the whole response.
The browser implementation seems to be struggling with this (I had to revert a similar change in #104384 due to test failures - console logs). cc: @pavelsavara

Given that this test is a copy-paste of existing test logic we have in this file, I'd keep it as-is in this PR.

@MihaZupan MihaZupan merged commit edab50b into dotnet:main Jul 8, 2024
81 of 83 checks passed
@MihaZupan MihaZupan added this to the 9.0.0 milestone Jul 8, 2024
@manandre manandre deleted the loadintobuffer-token branch July 8, 2024 21:43
@github-actions github-actions bot locked and limited conversation to collaborators Aug 9, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Net.Http community-contribution Indicates that the PR has been added by a community member new-api-needs-documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[API Proposal]: Expose overloads of HttpContent.LoadIntoBufferAsync taking a CancellationToken
4 participants