From 0bbbd8cfa2df665bc22a47831adf91668e391e3e Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Wed, 7 Dec 2011 02:03:05 +0000 Subject: http_file: use lower keepalive times under Linux TCP keepalives are inexpensive, so we can use them to monitor whether or not our connection is still alive while uploading. Remote servers make take an unpredictable amount of time to actually write out the data we've uploaded (and empty socket buffers to receive more), so it is extremely difficult to calculate an effective timeout for select() or poll(). --- lib/mogilefs/http_file.rb | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/mogilefs/http_file.rb b/lib/mogilefs/http_file.rb index b8bfd48..0d6faf5 100644 --- a/lib/mogilefs/http_file.rb +++ b/lib/mogilefs/http_file.rb @@ -1,5 +1,6 @@ # -*- encoding: binary -*- # here are internal implementation details, do not use them in your code +require 'socket' require 'stringio' require 'uri' require 'digest/md5' @@ -106,7 +107,7 @@ class MogileFS::HTTPFile < StringIO # returns file size if the socket finished writing def upload(devid, uri) # :nodoc: sock = MogileFS::Socket.tcp(uri.host, uri.port) - sock.setsockopt(Socket::IPPROTO_TCP, Socket::SO_KEEPALIVE, 1) + set_socket_options(sock) file_size = length if @streaming_io @@ -192,4 +193,27 @@ class MogileFS::HTTPFile < StringIO commit super end + + # :stopdoc: + # aggressive keepalive settings on Linux + Ruby 1.9.2+ + TCP_KEEPALIVE = { + :TCP_KEEPIDLE => 60, # seconds time before keepalive packet is sent + :TCP_KEEPINTVL => 5, + :TCP_KEEPCNT => 2, # number of retries + } + + req_consts = TCP_KEEPALIVE.keys + if (Socket.constants & req_consts).size == req_consts.size + def set_socket_options(sock) + sock.setsockopt(:SOL_SOCKET, :SO_KEEPALIVE, 1) + TCP_KEEPALIVE.each do |k,v| + sock.setsockopt(:IPPROTO_TCP, k, v) + end + end + else + def set_socket_options(sock) + sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1) + end + end + # :startdoc: end -- cgit v1.2.3-24-ge0c7