-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Invoke-RestMethod/WebRequest: Support CTRL-C when reading data using cancellation token #19315
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
Conversation
@CarloToso and @iSazonov - could you please provide some feedback on this approach. I have tested the scenarios in the linked bugs, as well as downloading with a stalling RSS feed using a custom minimal API test server and can confirm the CTRL-C and timeout works for me as expected with these changes. Also, modifying some of these files has given me a large number of codefactor issues that already existed in those files. Do these need to be fixed as part of this PR? |
@stevenebutler Fixing the codefactor issues would be good, you could also add some tests. |
@@ -563,12 +563,18 @@ protected override void ProcessRecord() | |||
|
|||
8000 using HttpResponseMessage response = GetResponse(client, request, handleRedirect); | |||
|
|||
if (TimeoutSec > 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This use of TimeOut sec is not correct, it should indicate the timeout before the connetion to the server, not during the download
test:
iwr https://software-static.download.prss.microsoft.com/dbazure/988969d5-f34g-4e03-ac9d-1f9786c66751/22621.525.220925-0207.ni_release_svc_refresh_CLIENTENTERPRISEEVAL_OEMRET_x64FRE_en-us.iso -Timeout 5
#--> fails after 5 seconds
It should only fail if Invoke-WebRequest cant connect to the server after trying for 5 seconds
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I did ask about this in #12249 comments. I thought this needed some discussion but wanted to get a working prototype out for discussion.
Should we use a second parameter like ReceiveTimeout with default of 5 minutes or do something else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the desired behaviour is checking if the download is stuck for 5 minutes and then closing the download with a warning message. At the moment your implementation halts the successful download after a timespan (-ReceiveTimeout) has passed. This could be a new feature (you should open an issue to discuss if we should implement it), but it's not the correct solution for issue #12249.
This PR at the moment fixes #16145 (Ctrl-c on download stuck because of no internet)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I see. I think implementing what you describe is likely to be a more complex patch as it would need to monitor the stream progress and adjust cancellation timeouts whenever data is received. Given this PR still address #16145 I think it would be good to submit (with the timeout removed) so that issue can be closed, if it is agreed that this is the correct way to deal with that issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will have to wait for @iSazonov 's rewiew, but it looks good to me 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My comment #12249 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iSazonov I have responded to your comment in the issue. I don't think using a separate task is the right solution as I have explained there. Could you please review this PR as it demonstrates that using a task is not necessary to support cancellation. Provided you are okay with the PR I will go back and fix the codefactor issues in the code base that are being flagged.
I will try to build timeout cancellation on top of this PR once it is approved using the approach I outlined in #12249.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI, I have fixed reported codefactor issues and merged recent changes from master branch.
I’m not sure how I could write tests for this. Do you have any suggestions? my testing so far was mostly ctrlc and time-out testing with pulling network cables. Is it possible to simulate ctrlc in a pester test? A timeout is possible to simulate if the test web server supports that but I haven’t looked at it’s capabilities yet. I wrote a simple minimal api test server that verified the cancellation token worked for the rss reader logic as well by writing out chunks of rss with delays. Should something like that get integrated into the test server (if it can’t already do this sort of thing)? |
@stevenebutler don't worry about the tests, I don't we can simulate accurately the issue this PR fixes |
6bb2521
to
bae7acd
Compare
bae7acd
to
835b508
Compare
This PR has Quantification details
Why proper sizing of changes matters
Optimal pull request sizes drive a better predictable PR flow as they strike a
What can I do to optimize my changes
How to interpret the change counts in git diff output
Was this comment helpful? 👍 :ok_hand: :thumbsdown: (Email) |
APIs that should be cancelled are passed the cancellation token and _cancelToken is configured with CancelAfter() when request timeout is specified.
Switched use of synchronous stream APIs to asynchronous APIs that use the cancellation token.
PR Summary
This PR closes #16145
The root cause of these issues was that once the response headers are read, the cancellation token was not always being passed to APIs that deal with reading the response stream.
In some scenarios, CTRL-C worked (where the cancellation token was being passed down), but this was not occurring in all scenarios and the use of blocking read APIs that do not take cancellation tokens prevented the early cancellation when CTRL-C was used.
PR Context
This PR helps because it allows all I/O in the web requests cmdlets to be cancelled if the user uses CTRL-C to terminate processing.
A previous iteration of this PR added a timeout, but was incorrect as the desired behaviour is to cancel if the connection is stalled for 5 minutes, not after a fixed timeout.
PR Checklist
.h
,.cpp
,.cs
,.ps1
and.psm1
files have the correct copyright headerWIP:
or[ WIP ]
to the beginning of the title (theWIP
bot will keep its status check atPending
while the prefix is present) and remove the prefix when the PR is ready.(which runs in a different PS Host).