diff options
author | Eric Wong <normalperson@yhbt.net> | 2011-11-04 23:50:17 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2011-11-04 23:50:17 +0000 |
commit | 8fefb8c07fdb69eb80c5aefbb0cdd74388cf908f (patch) | |
tree | 6ce410e52871a03750a3c1e1d68182dee9fb3a27 /lib/mogilefs/mogilefs.rb | |
parent | afe10667b8deeb60e3f70d2ddc7a20ae7e0bc072 (diff) | |
download | mogilefs-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.rb | 71 |
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 |