about summary refs log tree commit homepage
path: root/lib/mogilefs/http_file.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mogilefs/http_file.rb')
-rw-r--r--lib/mogilefs/http_file.rb26
1 files changed, 25 insertions, 1 deletions
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