class Hive::Device

The generic device class

Attributes

port_allocator[RW]
status[RW]
type[R]

Public Class Methods

new(options) click to toggle source

Initialise the device

# File lib/hive/device.rb, line 12
def initialize(options)
  @worker_pid = nil
  @options = options
  @port_allocator = options['port_allocator'] or Hive::PortAllocator.new(ports: [])
  @status = @options.has_key?('status') ? @options['status'] : 'none'
  @worker_class = self.class.to_s.sub('Device', 'Worker')
  require @worker_class.downcase.gsub(/::/, '/')
  raise ArgumentError, "Identity not set for #{self.class} device" if ! @identity
end

Public Instance Methods

==(other) click to toggle source

Test equality with another device

# File lib/hive/device.rb, line 92
def ==(other)
  self.identity == other.identity
end
claimed?() click to toggle source

Return true if the device is claimed If the device has no status set it is assumed not to be claimed

# File lib/hive/device.rb, line 87
def claimed?
  @status == 'claimed'
end
identity() click to toggle source

Return the unique identity of the device

# File lib/hive/device.rb, line 97
def identity
  "#{self.class.to_s.split('::').last}-#{@identity}"
end
running?() click to toggle source

Test the state of the worker process

# File lib/hive/device.rb, line 66
def running?
  if @worker_pid
    begin
      Process.kill 0, @worker_pid
      true
    rescue Errno::ESRCH
      false
    end
  else
    false
  end
end
start() click to toggle source

Start the worker process

# File lib/hive/device.rb, line 23
def start
  parent_pid = Process.pid
  @worker_pid = Process.fork do
    object = Object
    @worker_class.split('::').each { |sub| object = object.const_get(sub) }
    object.new(@options.merge('parent_pid' => parent_pid, 'device_identity' => self.identity, 'port_allocator' => self.port_allocator, 'hive_id' => Hive.hive_mind.device_details['id']))
  end
  Process.detach @worker_pid

  Hive.logger.info("Worker started with pid #{@worker_pid}")
end
stop() click to toggle source

Terminate the worker process

# File lib/hive/device.rb, line 36
def stop
  protect_file = File.expand_path("#{@worker_pid}.protect", PIDS_DIRECTORY)
  Hive.logger.debug("Checking for protected file: #{protect_file}")
  if File.exists? File.expand_path("#{@worker_pid}.protect", PIDS_DIRECTORY)
    Hive.logger.debug("PID #{@worker_pid} is protected")
    false
  else
    @stop_count = @stop_count.nil? ? 0 : @stop_count + 1

    if self.running?
      if @stop_count < 30
        Hive.logger.info("Attempting to terminate process #{@worker_pid} [#{@stop_count}]")
        Process.kill 'TERM', @worker_pid
      else
        Hive.logger.info("Killing process #{@worker_pid}")
        Process.kill 'KILL', @worker_pid if self.running?
      end
    end

    if self.running?
      false
    else
      @worker_pid = nil
      @stop_count = nil
      true
    end
  end
end
worker_pid() click to toggle source

Return the worker pid, checking to see if it is running first

# File lib/hive/device.rb, line 80
def worker_pid
  @worker_pid = nil if ! self.running?
  @worker_pid
end