-
Notifications
You must be signed in to change notification settings - Fork 151
Reading from stdout with timeout set can raise Timeout before it has occurred #207
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
Comments
Hey there, Does
|
This Works fine I did not read the updated timeout in 1.1.1 release docs
in the above code even though exit code returned should be 0 its giving None |
For reporting issues a reproducible example is very useful in getting good help. When calling Eg:
Or read from stdout without join:
See also Reading Partial Output of Commands That Do Not Terminate The timeout on run_command is actually for timing out on reading from stdout/stderr. This is confusing, would like to remove it and default to client timeout in Leaving open to make documentation better for timeouts and |
Thanks!! exit code issue is resolved using consume_output = True Yeah that will be great if only single timeout is kept instead of multiple timeouts In below code : output = client.run_command('pwd',return_list= True,stop_on_errors=False) getting timeout exception even though pwd is executed instantly. |
There is an issue with how Timeout is handled - it can raise Timeout early, before timeout value in seconds given, when the parallel client is busy with other commands. Have also made #208 to better handle |
Without using join method i tried with using stdout. Same is happening in stdout. Before timeout is reach its throwing timeout exception.
In above code its throwing timeout exception instead of consuming output from channel. ######Expected Behaviour###### #####Actual Behaviour####### Thanks |
Can't reproduce with run_command timeout:
|
In the above code in run_command if you give sudo=True parameter it throws Timeout exception but if you remove sudo = True it works fine. That is very strange any idea why is that ?? |
Does sudo work without a timeout? |
* Added ssh-python parallel and single client implementations * Updated readme, changelog and documentation * Re-do join with timeout to be on all commands rather than EAGAIN on any - #207 * Moved tests into their own packages
Yes without timeout sudo works |
Can't really say without code to reproduce. Will try again with sudo later on. There is likely still an issue with timeouts on run_command/reading from stdout but will need to reproduce it first. |
for _ in range(3): for _ in range(3): Above code gives timeout exception for _ in range(3): Above code works as well by removing timeout and writing sudo |
|
The above works on my system:
|
Which version are you using? |
for _ in range(5):
Above code throws timeout exception when trying to consume stdout for _ in range(5):
If i do not consume stdout it does not give timeout exception I tried running your code mentioned above but it threw exception in my system I am using latest version i.e. 1.12.0 |
Final Observations in run_command while consuming stdout Version 1.12.0:
|
For your use case best to use Am still unable to reproduce the above behaviour on my system. Can you please run the following:
And please attach the debug output on this issue. On my system:
|
DEBUG:pssh.clients.native.parallel:Make client request for host localhost, host in clients: False |
Yes, that looks like a similar bug to the one previously in Thanks for reporting and for the debug output. For the use case of seeing if a command would time out using |
If you can share snippet code for above two requirements that will of really help to me.
Thanks |
In above code stdout is empty list even cmd was executed I need to know how to handle timeout exception capturing host and command |
What you are describing is what Capturing partial output is described here. Eg:
Here is simple script to test read timeouts. Reading from
Outputs:
That means the command never finishes, likely sudo hanging waiting for input. Would also explain the early timeout - there is no stdout but it is timing out waiting for input. |
Thanks!! for the code snippet that really helps in my use case :) I got confuse in run_command timeout which i thought was that if there is continue output in stdout there will be no timeout, timeout will occur only when for the given timeout period there is nothing getting written on stdout My Understanding : Timeout given 5s, so if /dev/random continue to write in stdout there will be no timeout. Timeout will occur only when there is nothing on stdout for continue 5s Actual : Timeout will occur after 5s on stdout even though we are getting stdout |
Now only bug which i am facing is timeout with sudo(Direct Throws timeout exception) and sudo without timeout (stuck infinitely) in run_command |
Cannot reproduce the sudo behaviour. Likely your system requires password for sudo or is waiting for input, causing timeout to trigger from lack of stdout. Have separately been able to reproduce the timeout too early behaviour - see #180. It happens when an output stream has had no output - the library incorrectly raises timeout immediately in this case. This is likely the issue with sudo on your system - the command is not being run, no stdout to read, timeout raised too early. This also explains sudo being stuck without timeout if it is waiting on input and never terminates. Check stderr stream and confirm sudo works with ssh outside the library. Since cannot reproduce with password less sudo don't see any issue with sudo behaviour in the library.
That is correct. /dev/random can block though (see man page), which causes timeout. Reading from, eg, /dev/urandom which always has output and never blocks causes no timeouts and the command never terminates - reading from stdout is infinite. There is a bug here where timeout is raised when nothing has ever been written to the stdout stream at all, as above. This causes early timeouts. |
Okay, so help me understand the bug. When i give timeout as 5s and command is not run initially so no stdout hence timeout raised instantly whereas in actual behaviour it should wait for 5s and after that timeout. Above case will only happen when command is not run initially at all. If command is run initially after that if it blocks for 5s it will throw timeout such as case in /dev/random
This makes sense as it aligns with the bug, but still let me check once on my end. Thanks |
Easiest reproduction:
Timeout raised early, datetime value is < 1sec. Timeout raised early when trying to read from one output stream which has no data while the other output stream has pending data to read. If no stream has data timeout does not occur. Stream can be one of stdout, stderr, stdin. |
Thanks for helping!! Yes there was issue with sudo on my system its waiting for password input. So sudo works fine Any ETA on when above bug might get fix ?? |
So i tried to reproduce your above code : Suppose stdout stream has no data for specified timeout it will throw timeout exception instead further it should also be able to check in stderr stream and no data there for timeout than throw timeout. Because if in multiple commands any command try to write to stderr and i am capturing stdout first, so in failed command it will wait in stdout stream for timeout and without checking stderr will raise timeout. Code for reference :
Actual: Expected: I think along with timeout fix above case should also be handled. Thanks |
Yes, and that is covered. The read timeout should be per read buffer, so separate timeouts for stdout and stderr. This is to be able to capture output separately, otherwise it would not be known which output stream caused the timeout. The client code does not have to read stdout first, it might only check stderr, or both at once with parallel readers. Timeout exceptions should be able to be handled separately per stream, as per user requirements. In the above example timeout is raised (incorrectly) because there is output waiting on the stderr stream when reading from stdout. Once all stdout output is consumed and there is no more data in stdout, timeout is raised from unread data on stderr. The fix covers this case. |
Great!! I just thought of sharing it. How will i be able to read both streams parallel? |
Regular gevent code, eg:
Could spawn readers for all hosts before joining to read output from all hosts at once and so on. There's more code needed to correctly handle timeouts and stream restarts, this is a simple example. Can add some more complete examples in the documentation for doing this. A client function to gather all output in parallel might be useful - standard warnings about large outputs and memory use apply. PRs welcome for either.
|
Uh oh!
There was an error while loading. Please reload this page.
Issue 1:
I am using native client and my code is
hosts = ['localhost']
client = ParallelSSHClient(hosts)
output = client.run_command('uname;pwd',return_list = True)
client.join(output,timeout = 5)
###Expected behaviour####
It should execute and return the output of commands
###Actual Behaviour####
getting timeout exception
The same timeout when i am using with run_command its working fine but with join method its failing
Can you explain on what is difference between timeout use with run_command vs timeout use in join method
Issue 2:
What will be the case if i have entered host name wrong
hosts = ['localhost','wrong_host_name']
output = client.run_command('uname;sleep 10;pwd',return_list = True,timeout = 5)
###Expected behaviour####
for localhost : print uname and timeout after that
for wrong_host_name : show exception (As Expected)
###Actual Behaviour###
for localhost : print uname --> sleep for 10 --> print pwd
for wrong_host_name : wait for 10 sec to connect and after that throw exception
Please help me understand on how timeouts is working for
Issue 3:
If any host name is wrong in the list and I am not using any timeout throughout the script
client.join(output) is stuck indefinitely
Thanks
The text was updated successfully, but these errors were encountered: