dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.14k stars 4.71k forks source link

Blazor WASM not aborting socket on HttpClient cancellation #93930

Closed gilm0079 closed 1 month ago

gilm0079 commented 12 months ago

Description

I described the issue here thoroughly https://github.com/mono/mono/issues/21436 but maybe the mono repo was the wrong place to post this. I've been trying to keep an eye on similar issue requests, but the I haven't seen any traction on this.

In summary, in blazor wasm when a cancellation token is used to cancel an httpClient SendAsync the request correctly throws out in wasm, but the underlying socket is not aborted. The socket abort is essential to propagate up the cancellation token to the aspnetcore controller/action. I can verify using fiddler the socket remains open when wasm cancels the request. I can also verify that token propagation works on the server side (aspnetcore controller/action) if I force fiddler to abort the socket.

I've seen some similar issues related to the underlying socket handling (I'm not sure if mono is responsible or a javascript hook) where a pull request was completed for dotnet7 to add the socket cancellation, but I'm still seeing the issue on the latest stable version.

Reproduction Steps

Reproduction is 100% reliable.

Using the HttpClientFactory in blazor wasm, I create an instance of a named httpclient and execute a sendAsync against the blazor server. The blazor server action has a large "await Task.Delay" to simulate a heavy server operation. While waiting on the server side, I cancel the httpClient operation using the cancellationToken. The wasm code correctly cancels waiting on the SendAsync and throws out the cancellation exception. When using a network inspector (fiddler in my case), I can see that the socket is still active and not aborted as expected. The server is also still waiting on the task delay and aspnetcore has not issued a cancelled token for the request (because the socket is not aborted).

Expected behavior

When a token is cancelled in blazor wasm against the httpClient, besides the current behavior of cancelling waiting on the sendAsync and throwing the cancellation exception the underlying socket connection should be forcefully aborted.

Actual behavior

When a token is cancelled in blazor wasm against the httpClient, the sendAsync await is cancelled out and throws a cancellation exception but the socket connection remains active until the server completes the operation. This wastes server processing as it could have received a cancelled token from the aborted socket and stopped processing its workload.

Regression?

This has never worked correctly in Blazor wasm. It was talked about early (3.1 or 5). I had discussions about this not working while we were using dotnet6. It was pushed to the dotnet7 milestone. It looked like it was completed for the dotnet7 milestone, but I'm still seeing the incorrect behavior in blazor 7.0.10.

Known Workarounds

No known workarounds

Configuration

Blazor 7.0.10 Unsure which dotnet runtime is used when doing VS debugging. My dotnet --version reports 7.0.402, but I'm also running VS 2022 Pro 17.7.5 which I believe is bound to a specific SDK version. Windows 10 Pro 22H2 os build 19045.3570 x64 I'm currently debugging in chrome stable channel 118.0.5993.89

Other information

Feel free to reach out if you need more information on this. I don't have any details on where the bug may be. I don't have visibility into the socket handling when debugging from VS.

ghost commented 12 months ago

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

Issue Details
### Description I described the issue here thoroughly https://github.com/mono/mono/issues/21436 but maybe the mono repo was the wrong place to post this. I've been trying to keep an eye on similar issue requests, but the I haven't seen any traction on this. In summary, in blazor wasm when a cancellation token is used to cancel an httpClient SendAsync the request correctly throws out in wasm, but the underlying socket is not aborted. The socket abort is essential to propagate up the cancellation token to the aspnetcore controller/action. I can verify using fiddler the socket remains open when wasm cancels the request. I can also verify that token propagation works on the server side (aspnetcore controller/action) if I force fiddler to abort the socket. I've seen some similar issues related to the underlying socket handling (I'm not sure if mono is responsible or a javascript hook) where a pull request was completed for dotnet7 to add the socket cancellation, but I'm still seeing the issue on the latest stable version. ### Reproduction Steps Reproduction is 100% reliable. Using the HttpClientFactory in blazor wasm, I create an instance of a named httpclient and execute a sendAsync against the blazor server. The blazor server action has a large "await Task.Delay" to simulate a heavy server operation. While waiting on the server side, I cancel the httpClient operation using the cancellationToken. The wasm code correctly cancels waiting on the SendAsync and throws out the cancellation exception. When using a network inspector (fiddler in my case), I can see that the socket is still active and not aborted as expected. The server is also still waiting on the task delay and aspnetcore has not issued a cancelled token for the request (because the socket is not aborted). ### Expected behavior When a token is cancelled in blazor wasm against the httpClient, besides the current behavior of cancelling waiting on the sendAsync and throwing the cancellation exception the underlying socket connection should be forcefully aborted. ### Actual behavior When a token is cancelled in blazor wasm against the httpClient, the sendAsync await is cancelled out and throws a cancellation exception but the socket connection remains active until the server completes the operation. This wastes server processing as it could have received a cancelled token from the aborted socket and stopped processing its workload. ### Regression? This has never worked correctly in Blazor wasm. It was talked about early (3.1 or 5). I had discussions about this not working while we were using dotnet6. It was pushed to the dotnet7 milestone. It looked like it was completed for the dotnet7 milestone, but I'm still seeing the incorrect behavior in blazor 7.0.10. ### Known Workarounds No known workarounds ### Configuration Blazor 7.0.10 Unsure which dotnet runtime is used when doing VS debugging. My dotnet --version reports 7.0.402, but I'm also running VS 2022 Pro 17.7.5 which I believe is bound to a specific SDK version. Windows 10 Pro 22H2 os build 19045.3570 x64 I'm currently debugging in chrome stable channel 118.0.5993.89 ### Other information Feel free to reach out if you need more information on this. I don't have any details on where the bug may be. I don't have visibility into the socket handling when debugging from VS.
Author: gilm0079
Assignees: -
Labels: `area-System.Net.Http`
Milestone: -
ghost commented 12 months ago

Tagging subscribers to 'arch-wasm': @lewing See info in area-owners.md if you want to be subscribed.

Issue Details
### Description I described the issue here thoroughly https://github.com/mono/mono/issues/21436 but maybe the mono repo was the wrong place to post this. I've been trying to keep an eye on similar issue requests, but the I haven't seen any traction on this. In summary, in blazor wasm when a cancellation token is used to cancel an httpClient SendAsync the request correctly throws out in wasm, but the underlying socket is not aborted. The socket abort is essential to propagate up the cancellation token to the aspnetcore controller/action. I can verify using fiddler the socket remains open when wasm cancels the request. I can also verify that token propagation works on the server side (aspnetcore controller/action) if I force fiddler to abort the socket. I've seen some similar issues related to the underlying socket handling (I'm not sure if mono is responsible or a javascript hook) where a pull request was completed for dotnet7 to add the socket cancellation, but I'm still seeing the issue on the latest stable version. ### Reproduction Steps Reproduction is 100% reliable. Using the HttpClientFactory in blazor wasm, I create an instance of a named httpclient and execute a sendAsync against the blazor server. The blazor server action has a large "await Task.Delay" to simulate a heavy server operation. While waiting on the server side, I cancel the httpClient operation using the cancellationToken. The wasm code correctly cancels waiting on the SendAsync and throws out the cancellation exception. When using a network inspector (fiddler in my case), I can see that the socket is still active and not aborted as expected. The server is also still waiting on the task delay and aspnetcore has not issued a cancelled token for the request (because the socket is not aborted). ### Expected behavior When a token is cancelled in blazor wasm against the httpClient, besides the current behavior of cancelling waiting on the sendAsync and throwing the cancellation exception the underlying socket connection should be forcefully aborted. ### Actual behavior When a token is cancelled in blazor wasm against the httpClient, the sendAsync await is cancelled out and throws a cancellation exception but the socket connection remains active until the server completes the operation. This wastes server processing as it could have received a cancelled token from the aborted socket and stopped processing its workload. ### Regression? This has never worked correctly in Blazor wasm. It was talked about early (3.1 or 5). I had discussions about this not working while we were using dotnet6. It was pushed to the dotnet7 milestone. It looked like it was completed for the dotnet7 milestone, but I'm still seeing the incorrect behavior in blazor 7.0.10. ### Known Workarounds No known workarounds ### Configuration Blazor 7.0.10 Unsure which dotnet runtime is used when doing VS debugging. My dotnet --version reports 7.0.402, but I'm also running VS 2022 Pro 17.7.5 which I believe is bound to a specific SDK version. Windows 10 Pro 22H2 os build 19045.3570 x64 I'm currently debugging in chrome stable channel 118.0.5993.89 ### Other information Feel free to reach out if you need more information on this. I don't have any details on where the bug may be. I don't have visibility into the socket handling when debugging from VS.
Author: gilm0079
Assignees: -
Labels: `arch-wasm`, `area-System.Net.Http`, `os-browser`
Milestone: -
pavelsavara commented 3 months ago

Could you please test this with Net9 preview. There was significant rewrite since Net7.

gilm0079 commented 3 months ago

Will do. It may be a bit until I can test that. Starting a branch to convert our project from .net7 to 8. There are breaking changes in blazor in this transition. If all goes well making a .net9 preview branch should be easy. I'll keep you posted.

dotnet-policy-service[bot] commented 2 months ago

This issue has been marked needs-author-action and may be missing some important information.

dotnet-policy-service[bot] commented 1 month ago

This issue will now be closed since it had been marked no-recent-activity but received no further activity in the past 14 days. It is still possible to reopen or comment on the issue, but please note that the issue will be locked if it remains inactive for another 30 days.