-
Notifications
You must be signed in to change notification settings - Fork 653
An API for TCP timeouts #1415
Comments
You mean connect timeouts? Those could be implemented at the application level, if we supported canceling uv_connect_t requests. |
Yes, I mean connect timeouts in this context (although read/write timeouts in UV_RUN_DEFAULT could equally apply). I agree this can done at the application level for less than 2 minutes, that isn't too hard. You even have a test case in the code showing how to do it (test-tcp-connect-timeout.c). What I'm saying is the OS socket layer is cancelling the connection at 2 minutes. For my application I want to set a timeout for 10 minutes using methods similar to test-tcp-connect-timeout.c. But ETIMEDOUT will occur after 2 minutes. I believe the cause is: http://stackoverflow.com/questions/8471577/linux-tcp-connect-failure-with-etimedout Other applications I use (such as MySQL) aren't hit with this timeout but unfortunately I don't know enough low-level socket programming to understand why. To try this for yourself to connecting to port 81 of www.google.com using uv_tcp_connect and UV_RUN_DEFAULT. |
OK, done some research into this. Basically with MySQL as my example, they are doing a blocking connect, in which case the standard socket level timeouts apply. Libuv with UV_RUN_DEFAULT is doing a non-blocking connect and an epoll_wait with infinite timeout. the syn/ack retries are what causes the timeout. The only solution I have found is using setsockopt() to set TCP_SYNCNT to a higher number, setting it to 7 is about 4 minutes for example. Unfortunately this solution is not portable beyond Linux and I haven't even begun to test the behaviour of other operating systems. Suggested solutions:
|
Hi @LinuxJedi, I think documentation is the only way to "solve" this. libuv always uses sockets in non-blocking mode, regardless of the mode the loop is run on. Now, if all you have in the loop is a TCP handle trying to connect somewhere, then the loop will block for i/o for an infinite amount of time. If you would add a timer for X seconds then the loop would block for that amount of time (since it's the only timer). We could modify uv_cancel to allow it to cancel uv_connect requests, but that can only happen before libuv actually calls connect() (once the socket becomes readable), after that uv_cancel would return false and do nothing. I don't know if there is some system wide setting affecting this, which is of course platform dependent. AFAIS here: http://stackoverflow.com/questions/8471577/linux-tcp-connect-failure-with-etimedout the timeout is not just one value, it's a result of a linear and then a exponential backoff, at least in Linux, and TBH I have no idea if there is a way to affect it with a setsockopt which refers to time, rather than number of SYNs, which is very low-level. I'll leave this open for a while, maybe someone knows the answer to this... :-) |
Agreed, in the mean time I'll work on a fix for my code in the one scenario where I'm using UV_RUN_DEFAULT on connect :) |
Closing then! |
It would be nice to have an API for TCP timeouts. If for example you are doing a TCP connect with UV_RUN_DEFAULT in Linux you will hit a ETIMEDOUT after around 2 minutes.
I realise typical use case would be to run in UV_RUN_NOWAIT and have a timer for timeout but there are cases where you would not want to do this.
The text was updated successfully, but these errors were encountered: