Module: Regurgitator::Local

Included in:
FileRequest
Defined in:
lib/regurgitator/local.rb

Overview

:nodoc:

Constant Summary collapse

STORE_PATHS =

This is used to register local storage endpoints so we can short-circuit and avoid making HTTP requests to devices Must be configured by the user

Hash.new do |h,port|
  h[port] = {} # key: directory root path, value: whatever...
end.compare_by_identity

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.addrObject



22
23
24
# File 'lib/regurgitator/local.rb', line 22

def self.addr
  (@local_addrs_lock.synchronize { @local_addrs.first })[0]
end

.addrsObject



26
27
28
# File 'lib/regurgitator/local.rb', line 26

def self.addrs
  @local_addrs_lock.synchronize { @local_addrs.keys }
end

.include?(addr) ⇒ Boolean

Returns:

  • (Boolean)


18
19
20
# File 'lib/regurgitator/local.rb', line 18

def self.include?(addr)
  @local_addrs_lock.synchronize { @local_addrs.include?(addr) }
end

.refresh_addrs!Object

Normally not needed unless you dynamically bring up/down network devices. It may be useful to call this periodically or to integrate with some network device state monitoring system.



33
34
35
36
37
38
39
40
41
# File 'lib/regurgitator/local.rb', line 33

def self.refresh_addrs!
  @local_addrs_lock.synchronize do
    tmp = {}
    Socket.ip_address_list.keep_if do |ip|
      ip.ipv4? && ! ip.ipv4_multicast?
    end.each { |ip| tmp[ip.ip_address.freeze] = true }
    @local_addrs = tmp
  end
end

.register(tcp_port, directory_root) ⇒ Object

registers a local path for a given tcp_port and directory_root

Raises:

  • (ArgumentError)


45
46
47
48
49
50
# File 'lib/regurgitator/local.rb', line 45

def self.register(tcp_port, directory_root)
  directory_root = directory_root.gsub(%r{/+\z}, "")
  dev_dirs = Dir.foreach(directory_root).grep(/\Adev\d+\z/)
  raise ArgumentError, 'no /dev\d+/ directories found' if dev_dirs.empty?
  STORE_PATHS[tcp_port][directory_root] = Set.new(dev_dirs)
end

Instance Method Details

#device_path_stat(uri) ⇒ Object

returns nil if nothing was found returns a path and associated File::Stat to the local FS if a matching path is possible



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/regurgitator/local.rb', line 55

def device_path_stat(uri)
  Regurgitator::Local.include?(uri.host) or return
  (roots = STORE_PATHS[uri.port]).empty? and return
  uri.path =~ %r{\A/(dev\d+)/} or
          raise "BUG: path needs to match '\\A/dev\d+/' (#{uri})"
  devN = $1
  rv = nil
  roots.each do |root, dev_dirs|
    dev_dirs.include?(devN) or next
    begin
      path = "#{root}#{uri.path}"
      stat = File.stat(path)

      # multiple "/devN" paths for the same ports would be ambiguous,
      # so we cannot optimize away the HTTP request for those
      return nil if rv

      rv = [ path, stat ]
    rescue => e
      warn "E: #{e.message}, root=#{root} failed for #{uri}"
    end
  end

  rv
end

#trylocal(env, uri_group) ⇒ Object



81
82
83
84
85
86
87
88
89
# File 'lib/regurgitator/local.rb', line 81

def trylocal(env, uri_group)
  STORE_PATHS.empty? and return
  uri_group.flatten.each do |uri|
    path_stat = device_path_stat(uri) or next
    path, stat = path_stat
    return Regurgitator::LocalFile.new(env, path, uri, stat)
  end
  nil
end