# -*- encoding: binary -*- # helpers for device lookups module Regurgitator::Device include Regurgitator::ServerSettings # :stopdoc: REFRESH_DEVICE = <<-EOS SELECT d.devid, h.hostip, h.altip, h.altmask, h.http_port, h.http_get_port FROM device d LEFT JOIN host h ON d.hostid = h.hostid WHERE d.status IN ('readonly','alive','drain') AND h.status = 'alive' EOS DEVICES_ON = 'SELECT devid FROM file_on WHERE fid = ?' # :startdoc: def initialize(*args) # :nodoc: super init_device_ivars end def init_device_ivars @device_cache_mtime = Time.at(0) @device_cache = nil @device_cache_lock = Mutex.new end def self.extended(obj) obj.init_device_ivars end def device_uri_pair!(opts, get_port) rv = [ URI::HTTP.build(opts) ] if get_port opts[:port] = get_port rv << URI::HTTP.build(opts) end rv end # Returns a hash of device info with the Integer +devid+ # as the hash key. def refresh_device(force = false) # :nodoc: @device_cache_lock.synchronize { refresh_device_unlocked(force) } end def refresh_device_unlocked(force) # :nodoc: return @device_cache if ! force && ((Time.now - @device_cache_mtime) < 60) tmp = {}.compare_by_identity refresh_zone(force) @db[REFRESH_DEVICE].each do |x| # devices in "drain" status may hit raciness try those as a last resort x[:preferred] = !!(x[:d_status] =~ %r{\A(?:readonly|alive)\z}) hostip = x[:hostip] port = x[:http_port] || 80 get_port = x[:http_get_port] x[:ipaddr] = { :hostip => hostip } x[:zone] = zone_for(hostip) devid = x[:devid] o = { :path => "/dev#{devid}", :port => port, :host => hostip } x[:uris] = { :pri => device_uri_pair!(o, get_port) } x[:ipaddr][:altmask] = pat = Patricia.new altmask = x[:altmask] and pat.add(altmask) if altip = x[:altip] x[:ipaddr][:altip] = altip o[:host] = altip o[:port] = port x[:uris][:alt] = device_uri_pair!(o, get_port) end tmp[devid] = x end Regurgitator::Local.refresh_addrs! @device_cache_mtime = Time.now @device_cache = tmp end end