You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
All operations except for get_multi do not respect the socket_timeout client option. I think this ultimately boils down to the usage of getshere and why in a patch using IO#timeout it works as expected (operation times out).
Reproduction
I've tested the following script on various Ruby versions and none of them time out on the Memcached call as I would expect. Note that I at least expect on Ruby versions < 3.0 it properly times out since SO_RCVTIMEO and SO_SNDTIMEO would be used since it's a blocking socket.
The gist of the script is configuring a Dalli client with a 100ms socket_timeout and using Toxiproxy to inject 5 seconds of latency to each call to Memcached. The expected behaviour is that the c.get("foo") line should time out after 100ms; but in reality it hangs 10 seconds (5s for the initial version call + 5s for the get call) on the gets("\r\n") line I referenced above.
I assume that this test was supposed to catch this bug but I don't think it does because:
a) the default timeout of 1s is less than the sleep duration (0.6s + 0.3s)
b) If you pass in socket_timeout: 1000 and remove the sleep, the test still passes
Note: If I replace the get call with get_multi, there is a timeout: W, [2024-11-12T11:31:08.099162 #59436] WARN -- : 127.0.0.1:22122 failed (count: 0) External timeout.
I have a branch that has been running in production for a couple of days without any issue that leverages IO#timeouthere. I can submit a patch if you're willing to accept it @petergoldstein. Although longer term, the BufferedIO class in redis-client seems like the proper way to handle timeouts.
The text was updated successfully, but these errors were encountered:
nickamorim
changed the title
socket_timeout does not worksocket_timeout does not work in CRuby > 3.0
Nov 14, 2024
Description
All operations except for
get_multi
do not respect thesocket_timeout
client option. I think this ultimately boils down to the usage ofgets
here and why in a patch usingIO#timeout
it works as expected (operation times out).Reproduction
I've tested the following script on various Ruby versions and none of them time out on the Memcached call as I would expect. Note that I at least expect on Ruby versions < 3.0 it properly times out since
SO_RCVTIMEO
andSO_SNDTIMEO
would be used since it's a blocking socket.The gist of the script is configuring a Dalli client with a 100ms
socket_timeout
and using Toxiproxy to inject 5 seconds of latency to each call to Memcached. The expected behaviour is that thec.get("foo")
line should time out after 100ms; but in reality it hangs 10 seconds (5s for the initialversion
call + 5s for theget
call) on thegets("\r\n")
line I referenced above.I assume that this test was supposed to catch this bug but I don't think it does because:
a) the default timeout of 1s is less than the
sleep
duration (0.6s + 0.3s)b) If you pass in
socket_timeout: 1000
and remove thesleep
, the test still passesNote: If I replace the
get
call withget_multi
, there is a timeout:W, [2024-11-12T11:31:08.099162 #59436] WARN -- : 127.0.0.1:22122 failed (count: 0) External timeout
.My understanding is that this is because we call
readfull
which ultimately callsread_nonblock
and hitsnonblock_timed_out?
.Proposed Solution
I have a branch that has been running in production for a couple of days without any issue that leverages
IO#timeout
here. I can submit a patch if you're willing to accept it @petergoldstein. Although longer term, theBufferedIO
class in redis-client seems like the proper way to handle timeouts.The text was updated successfully, but these errors were encountered: