Class: Hive::Device

Inherits:
Object
  • Object
show all
Defined in:
lib/hive/device.rb,
lib/hive/device/shell.rb

Overview

The generic device class

Direct Known Subclasses

Shell

Defined Under Namespace

Classes: Shell

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Device

Initialise the device

Raises:

  • (ArgumentError)


12
13
14
15
16
17
18
19
20
# 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

Instance Attribute Details

#port_allocator ⇒ Object

Returns the value of attribute port_allocator.



9
10
11
# File 'lib/hive/device.rb', line 9

def port_allocator
  @port_allocator
end

#status ⇒ Object

Returns the value of attribute status.



8
9
10
# File 'lib/hive/device.rb', line 8

def status
  @status
end

#type ⇒ Object (readonly)

Returns the value of attribute type.



7
8
9
# File 'lib/hive/device.rb', line 7

def type
  @type
end

Instance Method Details

#==(other) ⇒ Object

Test equality with another device



92
93
94
# File 'lib/hive/device.rb', line 92

def ==(other)
  self.identity == other.identity
end

#claimed? ⇒ Boolean

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

Returns:

  • (Boolean)


87
88
89
# File 'lib/hive/device.rb', line 87

def claimed?
  @status == 'claimed'
end

#identity ⇒ Object

Return the unique identity of the device



97
98
99
# File 'lib/hive/device.rb', line 97

def identity
  "#{self.class.to_s.split('::').last}-#{@identity}"
end

#running? ⇒ Boolean

Test the state of the worker process

Returns:

  • (Boolean)


66
67
68
69
70
71
72
73
74
75
76
77
# 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 ⇒ Object

Start the worker process



23
24
25
26
27
28
29
30
31
32
33
# 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 ⇒ Object

Terminate the worker process



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# 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 ⇒ Object

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



80
81
82
83
# File 'lib/hive/device.rb', line 80

def worker_pid
  @worker_pid = nil if ! self.running?
  @worker_pid
end