about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-11-21 00:06:23 +0000
committerEric Wong <normalperson@yhbt.net>2011-11-21 00:20:34 +0000
commit126019445776ed08dd33d60e146a9d2e5786cf7c (patch)
tree682f4b7a77cef526886e753602cd4a5c8ef22f77
parenta292a04a7e8c7cf65b6f9a7462c97b10010e4877 (diff)
downloadmogilefs-client-126019445776ed08dd33d60e146a9d2e5786cf7c.tar.gz
Uploading large files can cause the destination to take
equally long to respond, either because of extra I/O
needed to verify or because we've hit fsync(2) or similar.
-rw-r--r--lib/mogilefs/http_file.rb17
1 files changed, 16 insertions, 1 deletions
diff --git a/lib/mogilefs/http_file.rb b/lib/mogilefs/http_file.rb
index 1611a5d..b08abaa 100644
--- a/lib/mogilefs/http_file.rb
+++ b/lib/mogilefs/http_file.rb
@@ -20,7 +20,19 @@ class MogileFS::HTTPFile < StringIO
   end
   class NonRetryableError < MogileFS::Error; end
 
+  # :stopdoc:
   MD5_TRAILER_NODES = {} # :nodoc: # EXPERIMENTAL
+  class << self
+    attr_accessor :response_timeout_cb
+  end
+
+  @response_timeout_cb = lambda do |elapsed_time, bytes_uploaded|
+    mbytes_uploaded = bytes_uploaded / (1024.0 * 1024.0)
+    # assumes worst case is 10M/s on the remote storage disk
+    t = mbytes_uploaded * 10 + elapsed_time
+    t < 5 ? 5 : t
+  end
+  # :startdoc:
 
   ##
   # The URI this file will be stored to.
@@ -94,6 +106,7 @@ class MogileFS::HTTPFile < StringIO
   # Writes an HTTP PUT request to +sock+ to upload the file and
   # returns file size if the socket finished writing
   def upload(devid, uri) # :nodoc:
+    start = Time.now
     sock = MogileFS::Socket.tcp(uri.host, uri.port)
     file_size = length
 
@@ -119,7 +132,9 @@ class MogileFS::HTTPFile < StringIO
       request_put(sock, uri, file_size, self)
     end
 
-    case line = sock.timed_read(23, "")
+    tout = self.class.response_timeout_cb.call(Time.now - start, file_size)
+
+    case line = sock.timed_read(23, "", tout)
     when %r{^HTTP/\d\.\d\s+(2\d\d)\s} # success!
       file_size
     when nil