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
Invoke-Restmethode won't timeout #12249
Comments
@KrX3D Please share PSVertionTable as issue template requested. |
Ah sorry here it is for PS7 which does not work:
And here for PS5 which does work:
|
Please check with 7.1 Preview1 |
i tried it with the preview version. Still the same problem:
|
Hello, |
I think it is easy to implement. PowerShell/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/StreamHelper.cs Line 278 in c22ccbe
accept a cancelation token so CancellationTokenSource could be initialized with a default timeout like 300 seconds. |
We should also ensure that |
TimeoutSec is used in HttpClient as connection timeout. |
ok, but still the Invoke-Rest Comand should timeout after 5 minutes in PS7 like it does in PS5 and not hang for eternity |
i updated my first post and removed the timeout parameter. |
i tried it with PS 7.1 but still the same, the script "hangs" forever in the invoke-restmethode function and does nothing. so if i download something and my router disconnects, PS stays at Invoke-Restmethode fir eternity
|
I think the problem starts here: Line 1255 in 4c586a7
If i shut down the wifi while downloading a file (without -OutFile), the download hangs forever and I can't manually stop the process with Ctrl+C |
@CarloToso I discussed this problem in the .Net Runtime repository. The problem is that the cancel token is used for this method, but not for the lower methods it uses (or rather it is not passed to the streams it uses). And the .Net team did not agree to change this. |
Yes, powershell requires thread timeout.but: |
If the Currently the canceltoken is only used as far as sending the request and receiving the response headers and is then ignored in many methods that read the response data. Many of these methods don't accept a cancellation token, but it might be possible to make use of variants that do. @iSazonov you stated the TimeoutSec is only used for the connection timeout. Should we add a second timeout for receiving data (e.g. ReceiveTimeout) with a reasonably high default (e.g. 5 minutes to make it similar to PS 5.1)? and pass that cancellation token to the stream handling routines? |
I have made changes to my local tree that works by passing the cancellation token through to all stream APIs. I had to substitute use of synchronous APIs for asynchronous APIs and pass the cancellation token to those, and use Because CTRL-C StopProcessing cancels the cancellationToken, this fixes issues where CTRL-C was being ignored inside the stream readers. The response read timeout is handled by adding the code below following the acquisition of the if (TimeoutSec > 0)
{
// Set timeout for receiving the data from the HTTP response stream
_cancelToken.CancelAfter(TimeSpan.FromSeconds(TimeoutSec));
} |
I said about HttpClient implementation.
I take it that if during any operation any request hangs for this time (network loss), then the cmdlet should terminate. |
@iSazonov it should be possible to do this without using a separate task provided the cancellation token we already have is passed through to low levels. I believe my WIP PR already demonstrates this for the CTRL-C issue and will need some additional work to support timing out when no traffic is received for a period of time (TimeoutSec). The reason HttpClient timeout is not in play anymore is because once data is being read from the stream directly, the HttpClient API is no longer being used. The streams APIs used to do this have cancellation support if the Async APIs are used, so it is possible to implement timeouts using the cancellation token while reading from the streams. Because of this I don't think the CmdLet needs to, or even should use a separate task to support cancellation and timeouts. If the task is cancelled it will return to the user, but unless the cancellation token also cancels the underlying operations, they will continue even though the cmdlet appears to be finished. If the cancellation token is passed down to those underlying operations instead, when the cancellation token is cancelled it will abort the underlying operations. The trick with this issue is that rather than using a straight timeout, the cancellation token timeout needs to be reset whenever data is received on the connection. If the cancellation token source is available to the underlying layers that are reading from the socket, it is possible to reset the timeout every time data is read by calling cts.CancelAfter(timeoutVal). The second problem with using a task in the cmdlet is it will not be able to write progress or output to the stream from that task directly since it will likely be running in a separate thread and PowerShell does not support using WriteXXX APIs outside the main thread if I recall correctly. I haven't tried to implement this as I'd like to work on PR #19315 which is simpler and fixes the CTRL-C support first before implementing a fix for this issue in the interests of keeping the PR small and easier to review. |
The problem is that when we pass a CTS into the .Net API it does not guarantee that this CTS will work as we expect, because there can be many layers within that API. |
The .NET APIs that take cancellation tokens do work with the cancellation token. The issue you're describing is that HttpClient and handler, take timeouts properties but don't cancel the request when they are no longer effectively controlling them because they have handed off the response stream to be read independently. The HttpClient is not providing cancellation token to the underlying stream to cancel them because it is not reading them. The streams APIs take the cancellation token in the supported API calls and don't save a reference to the token so if they are read without passing a token they cannot be cancelled. When reading the streams if no cancellation token is passed to them, they have no way of being cancelled. If a separate task is used, how would the supervisor then monitor the stream for activity so it can reset the cancellation timeout whenever traffic is received? The requirement is for a timeout on no stream activity over a period of time (the TimeoutSec), not a straight-forward timeout from the start of the response. .NET core onwards is heavily biased towards cancellable asynchronous APIs so we should take advantage of them where it makes sense. Please have a look at PR#19330 which uses the cancellable APIs to make CTRL-C work. With some additional logic to reset the cancellation token timeout whenever data is read from the stream it should be possible to do similar for this issue. |
They work. But not always as you expected. See dotnet/runtime#74568 |
🎉This issue was addressed in #19558, which has now been successfully released as Handy links: |
Steps to reproduce
Hello,
i got this code here for demonstration:
Invoke-RestMethod -uri "https://XXXXXX.blob.core.windows.net/XXXXXXXX/XXXXXX/SOURCES/PE10.WIM?st=2020-02-20T13%3A08%3A43Z&se=2021-02-21T13%3A08%3A00Z&sp=racwdl&sv=2018-03-28&sr=b&sig=SIGNATURE" -OutFile "C:\Users\testUser\Downloads\DL\PRG\test.wim"
when i use that code i can get the download.
Firstly to maybe make clear what the parameter TimeoutSec should do. i thought it the connection stops i get an timeout after 10 seconds? or do i get an timeout after 10 seconds when i cant get an answer ?
To the problem: when i use that code above the download starts with Powershell 7. When i unplug my Lan cable when the download is already progressing, i can reattach the cable in maybe 10 seconds and the download resumes. when i leave it unpluged this happens:
in Powershell 5: i get an timeout after 5 minutes. and the script goes on (thats what i want)
in Powershell 7: nothing happens, waiting 5, 10 minutes, even hours (tested till 1 day) and its stuck. also the script is stuck and wont progress anymore
Expected behavior
Environment data
The text was updated successfully, but these errors were encountered: