diff options
author | Eric Wong <normalperson@yhbt.net> | 2013-10-18 10:28:18 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2013-10-18 10:28:18 +0000 |
commit | ab067831e707b191d6dfdcd01de1f1d85fc90d05 (patch) | |
tree | b02861eb1521fb325ee4e1d91e1a194ca73e7a9e /lib/yahns/client_expire.rb | |
download | yahns-ab067831e707b191d6dfdcd01de1f1d85fc90d05.tar.gz |
Diffstat (limited to 'lib/yahns/client_expire.rb')
-rw-r--r-- | lib/yahns/client_expire.rb | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/lib/yahns/client_expire.rb b/lib/yahns/client_expire.rb new file mode 100644 index 0000000..7da9498 --- /dev/null +++ b/lib/yahns/client_expire.rb @@ -0,0 +1,40 @@ +# Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors +# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt) + +# included in Yahns::HttpClient +# +# this provides the ability to expire idle clients once we hit a soft limit +# on idle clients +# +# we absolutely DO NOT issue IO#close in here, only BasicSocket#shutdown +module Yahns::ClientExpire # :nodoc: + def yahns_expire(timeout) # rarely called + return 0 if closed? # still racy, but avoid the exception in most cases + + info = Raindrops::TCP_Info.new(self) + return 0 if info.tcpi_state != 1 # TCP_ESTABLISHED == 1 + + # Linux struct tcp_info timers are in milliseconds + timeout *= 1000 + + send_timedout = !!(info.tcpi_last_data_sent > timeout) + + # tcpi_last_data_recv is not valid unless tcpi_ato (ACK timeout) is set + if 0 == info.tcpi_ato + sd = send_timedout && (info.tcpi_last_ack_recv > timeout) + else + sd = send_timedout && (info.tcpi_last_data_recv > timeout) + end + if sd + shutdown + 1 + else + 0 + end + # we also do not expire UNIX domain sockets + # (since those are the most trusted of local clients) + # the IO#closed? check is racy + rescue + 0 + end +end |