diff options
author | Eric Wong <e@80x24.org> | 2013-11-01 00:04:59 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2013-11-01 00:04:59 +0000 |
commit | 7c32323bdd375b1167b42991c081e3b579ad8243 (patch) | |
tree | d044e1a6810437d331e2f3d54c974ca45400877b /lib/yahns/client_expire_tcpi.rb | |
parent | 885b2f28f3b31539140a8466e6205903bc7cf1d2 (diff) | |
download | yahns-7c32323bdd375b1167b42991c081e3b579ad8243.tar.gz |
It's conceivable a sub-optimally configured instance can have too many Unix sockets connected to us. This also implements expiry for systems without sufficient "struct tcp_info" support.
Diffstat (limited to 'lib/yahns/client_expire_tcpi.rb')
-rw-r--r-- | lib/yahns/client_expire_tcpi.rb | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/lib/yahns/client_expire_tcpi.rb b/lib/yahns/client_expire_tcpi.rb new file mode 100644 index 0000000..8a89a42 --- /dev/null +++ b/lib/yahns/client_expire_tcpi.rb @@ -0,0 +1,41 @@ +# Copyright (C) 2013, Eric Wong <normalperson@yhbt.net> and all contributors +# License: GPLv3 or later (https://www.gnu.org/licenses/gpl-3.0.txt) +require 'raindrops' + +# 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::ClientExpireTCPI # :nodoc: + def yahns_expire(timeout) # rarely called + return 0 if closed? + + info = Raindrops::TCP_Info.new(self) + return 0 if info.state != 1 # TCP_ESTABLISHED == 1 + + # Linux struct tcp_info timers are in milliseconds + timeout *= 1000 + + send_timedout = !!(info.last_data_sent > timeout) + + # tcpi_last_data_recv is not valid unless tcpi_ato (ACK timeout) is set + if 0 == info.ato + sd = send_timedout && (info.last_ack_recv > timeout) + else + sd = send_timedout && (info.last_data_recv > timeout) + end + if sd + shutdown + 1 + else + 0 + end + # shutdown may race with the shutdown in http_response_done + rescue + 0 + end +# FreeBSD has "struct tcp_info", too, but does not support all the fields +# Linux does as of FreeBSD 9 (haven't checked FreeBSD 10, yet). +end if RUBY_PLATFORM =~ /linux/ |