about summary refs log tree commit homepage
path: root/lib/mogilefs/mogilefs.rb
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-11-04 23:50:17 +0000
committerEric Wong <normalperson@yhbt.net>2011-11-04 23:50:17 +0000
commit8fefb8c07fdb69eb80c5aefbb0cdd74388cf908f (patch)
tree6ce410e52871a03750a3c1e1d68182dee9fb3a27 /lib/mogilefs/mogilefs.rb
parentafe10667b8deeb60e3f70d2ddc7a20ae7e0bc072 (diff)
downloadmogilefs-client-8fefb8c07fdb69eb80c5aefbb0cdd74388cf908f.tar.gz
This is cleaner and replaces redundant code where we would retry
paths.  MogileFS::MogileFS#size now raises on error instead of
returning nil.
Diffstat (limited to 'lib/mogilefs/mogilefs.rb')
-rw-r--r--lib/mogilefs/mogilefs.rb71
1 files changed, 10 insertions, 61 deletions
diff --git a/lib/mogilefs/mogilefs.rb b/lib/mogilefs/mogilefs.rb
index f064d43..e0df888 100644
--- a/lib/mogilefs/mogilefs.rb
+++ b/lib/mogilefs/mogilefs.rb
@@ -1,6 +1,7 @@
 # -*- encoding: binary -*-
 require 'mogilefs/client'
 require 'mogilefs/util'
+require 'mogilefs/http_reader'
 
 ##
 # MogileFS File manipulation client.
@@ -57,22 +58,10 @@ class MogileFS::MogileFS < MogileFS::Client
   ##
   # Retrieves the contents of +key+.
 
-  def get_file_data(key, &block)
-    paths = get_paths(key) or return nil
-    paths.each do |path|
-      begin
-        sock = http_read_sock(URI.parse(path))
-        begin
-          return yield(sock) if block_given?
-          return sock.read(sock.mogilefs_size, "", @get_file_data_timeout)
-        ensure
-          sock.close rescue nil
-        end
-      rescue MogileFS::Timeout, MogileFS::InvalidResponseError,
-             Errno::ECONNREFUSED, EOFError, SystemCallError
-      end
-    end
-    nil
+  def get_file_data(key)
+    paths = get_paths(key)
+    sock = MogileFS::HTTPReader.first(paths, "GET", @get_file_data_timeout)
+    block_given? ? yield(sock) : sock.to_s
   end
 
   ##
@@ -200,20 +189,13 @@ class MogileFS::MogileFS < MogileFS::Client
   # Returns the size of +key+.
   def size(key)
     @backend.respond_to?(:_size) and return @backend._size(domain, key)
-    paths = get_paths(key) or return nil
+    paths = get_paths(key)
     paths_size(paths)
   end
 
   def paths_size(paths)
-    paths.each do |path|
-      begin
-        return http_read_sock(URI.parse(path), "HEAD").mogilefs_size
-      rescue MogileFS::InvalidResponseError, MogileFS::Timeout,
-             Errno::ECONNREFUSED, EOFError, SystemCallError => err
-        next
-      end
-    end
-    nil
+    sock = MogileFS::HTTPReader.first(paths, "HEAD", @get_file_data_timeout)
+    sock.content_length
   end
 
   ##
@@ -236,45 +218,12 @@ class MogileFS::MogileFS < MogileFS::Client
     if block_given?
       # emulate the MogileFS::Mysql interface, slowly...
       keys.each do |key|
-        paths = get_paths(key) or next
-        length = paths_size(paths) or next
+        paths = get_paths(key)
+        length = paths_size(paths)
         yield key, length, paths.size
       end
     end
 
     [ keys, res['next_after'] ]
   end
-
-  protected
-
-    # given a URI, this returns a readable socket with ready data from the
-    # body of the response.
-    def http_read_sock(uri, http_method = "GET")
-      tout = @get_file_data_timeout
-      sock = MogileFS::Socket.tcp(uri.host, uri.port, tout)
-      buf = "#{http_method} #{uri.request_uri} HTTP/1.0\r\n\r\n" # no chunking
-
-      sock.timed_write(buf, tout)
-      sock.timed_peek(4096, buf, tout) or
-        raise MogileFS::InvalidResponseError, "EOF on #{http_method} #{uri}"
-
-      head, body = buf.split(/\r\n\r\n/, 2)
-
-      # we're dealing with a seriously slow/stupid HTTP server if we can't
-      # get the header in a single recv(2) syscall.
-      if head =~ %r{\AHTTP/\d+\.\d+\s+200\s*} &&
-         head =~ %r{^Content-Length:\s*(\d+)}i
-        sock.mogilefs_size = $1.to_i
-        case http_method
-        when "HEAD"
-          sock.close
-        when "GET"
-          sock.read(head.size + 4) # will allow IO.copy_stream to work
-        end
-        return sock
-      end
-      sock.close rescue nil
-      raise MogileFS::InvalidResponseError,
-            "#{http_method} on #{uri} returned: #{head.inspect}"
-    end
 end