Object
MogileFS::Backend communicates with the MogileFS trackers.
Adds MogileFS commands names.
# File lib/mogilefs/backend.rb, line 13 def self.add_command(*names) names.each do |name| define_method name do |*args| do_request name, args.first || {} end end end
this converts an error code from a mogilefsd tracker to an exception:
Examples of some exceptions that get created:
class AfterMismatchError < MogileFS::Error; end class DomainNotFoundError < MogileFS::Error; end class InvalidCharsError < MogileFS::Error; end
# File lib/mogilefs/backend.rb, line 29 def self.add_error(err_snake) err_camel = err_snake.gsub(/(?:^|_)([a-z])/) { $1.upcase } err_camel << 'Error' unless /Error\z/ =~ err_camel unless self.const_defined?(err_camel) self.class_eval("class #{err_camel} < MogileFS::Error; end") end BACKEND_ERRORS[err_snake] = self.const_get(err_camel) end
Creates a new MogileFS::Backend.
:hosts is a required argument and must be an Array containing one or more ‘hostname:port’ pairs as Strings.
:timeout adjusts the request timeout before an error is returned.
# File lib/mogilefs/backend.rb, line 56 def initialize(args) @hosts = args[:hosts] raise ArgumentError, "must specify at least one host" unless @hosts raise ArgumentError, "must specify at least one host" if @hosts.empty? unless @hosts == @hosts.select { |h| h =~ /:\d+$/ } then raise ArgumentError, ":hosts must be in 'host:port' form" end @mutex = Mutex.new @timeout = args[:timeout] || 3 @socket = nil @lasterr = nil @lasterrstr = nil @dead = {} end
Performs the cmd request with args.
# File lib/mogilefs/backend.rb, line 153 def do_request(cmd, args) @mutex.synchronize do request = make_request cmd, args begin bytes_sent = socket.send request, 0 rescue SystemCallError shutdown raise MogileFS::UnreachableBackendError end unless bytes_sent == request.length then raise MogileFS::RequestTruncatedError, "request truncated (sent #{bytes_sent} expected #{request.length})" end readable? parse_response(socket.gets) end end
this converts an error code from a mogilefsd tracker to an exception Most of these exceptions should already be defined, but since the MogileFS server code is liable to change and we may not always be able to keep up with the changes
# File lib/mogilefs/backend.rb, line 186 def error(err_snake) BACKEND_ERRORS[err_snake] || self.class.add_error(err_snake) end
Makes a new request string for cmd and args.
# File lib/mogilefs/backend.rb, line 178 def make_request(cmd, args) "#{cmd} #{url_encode args}\r\n" end
Turns the line response from the server into a Hash of options, an error, or raises, as appropriate.
# File lib/mogilefs/backend.rb, line 194 def parse_response(line) if line =~ /^ERR\s+(\w+)\s*(.*)/ then @lasterr = $1 @lasterrstr = $2 ? url_unescape($2) : nil raise error(@lasterr), @lasterrstr return nil end return url_decode($1) if line =~ /^OK\s+\d*\s*(\S*)/ raise MogileFS::InvalidResponseError, "Invalid response from server: #{line.inspect}" end
Raises if the socket does not become readable in +@timeout+ seconds.
# File lib/mogilefs/backend.rb, line 211 def readable? timeleft = @timeout peer = nil loop do t0 = Time.now found = IO.select([socket], nil, nil, timeleft) return true if found && found[0] timeleft -= (Time.now - t0) if timeleft < 0 peer = @socket ? "#{@socket.mogilefs_peername} " : nil # we DO NOT want the response we timed out waiting for, to crop up later # on, on the same socket, intersperesed with a subsequent request! so, # we close the socket if it times out like this shutdown raise MogileFS::UnreadableSocketError, "#{peer}never became readable" break end shutdown end false end
Returns a socket connected to a MogileFS tracker.
# File lib/mogilefs/backend.rb, line 238 def socket return @socket if @socket and not @socket.closed? now = Time.now @hosts.sort_by { rand(3) - 1 }.each do |host| next if @dead.include? host and @dead[host] > now - 5 begin @socket = Socket.mogilefs_new(*(host.split(/:/) << @timeout)) rescue SystemCallError, MogileFS::Timeout @dead[host] = now next end return @socket end raise MogileFS::UnreachableBackendError end
Turns a url params string into a Hash.
# File lib/mogilefs/backend.rb, line 262 def url_decode(str) Hash[*(str.split(/&/).map { |pair| pair.split(/=/, 2).map { |x| url_unescape(x) } } ).flatten] end
Turns a Hash (or Array of pairs) into a url params string.
# File lib/mogilefs/backend.rb, line 271 def url_encode(params) params.map do |k,v| "#{url_escape k.to_s}=#{url_escape v.to_s}" end.join("&") end
(Not documented)
# File lib/mogilefs/backend.rb, line 280 def url_escape(str) str.gsub(/([^\w\,\-.\/\\\: ])/) { "%%%02x" % $1.ord }.tr(' ', '+') end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.