Class: CloudCrowd::NodeRecord

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
lib/cloud_crowd/models/node_record.rb

Overview

A NodeRecord is the central server’s record of a Node running remotely. We can use it to assign WorkUnits to the Node, and keep track of its status. When a Node exits, it destroys this record.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.check_in(params, request) ⇒ Object

Register a Node with the central server. Currently this only happens at Node startup.



22
23
24
25
26
27
28
29
30
31
# File 'lib/cloud_crowd/models/node_record.rb', line 22

def self.check_in(params, request)
  attrs = {
    :ip_address       => request.ip,
    :port             => params[:port],
    :busy             => params[:busy],
    :max_workers      => params[:max_workers],
    :enabled_actions  => params[:enabled_actions]
  }
  self.find_or_create_by_host(params[:host]).update_attributes!(attrs)
end

Instance Method Details

#actionsObject

What Actions is this Node able to run?



51
52
53
# File 'lib/cloud_crowd/models/node_record.rb', line 51

def actions
  @actions ||= enabled_actions.split(',')
end

#busy?Boolean

Is this Node too busy for more work? Determined by number of workers, or the Node’s load average, as configured in config.yml.

Returns:

  • (Boolean)


57
58
59
# File 'lib/cloud_crowd/models/node_record.rb', line 57

def busy?
  busy || (max_workers && work_units.count >= max_workers)
end

#display_statusObject

The printable status of the Node.



74
75
76
# File 'lib/cloud_crowd/models/node_record.rb', line 74

def display_status
  busy? ? 'busy' : 'available'
end

#nodeObject

Keep a RestClient::Resource handy for contacting the Node, including HTTP authentication, if configured.



69
70
71
# File 'lib/cloud_crowd/models/node_record.rb', line 69

def node
  @node ||= RestClient::Resource.new(url, CloudCrowd.client_options)
end

#release_work_unitsObject

Release all of this Node’s WorkUnits for other nodes to take.



84
85
86
# File 'lib/cloud_crowd/models/node_record.rb', line 84

def release_work_units
  WorkUnit.update_all('node_record_id = null, worker_pid = null', "node_record_id = #{id}")
end

#send_work_unit(unit) ⇒ Object

Dispatch a WorkUnit to this node. Places the node at back at the end of the rotation. If we fail to send the WorkUnit, we consider the node to be down, and remove this record, freeing up all of its checked-out work units. If the Node responds that it’s overloaded, we mark it as busy. Returns true if the WorkUnit was dispatched successfully.



38
39
40
41
42
43
44
45
46
47
48
# File 'lib/cloud_crowd/models/node_record.rb', line 38

def send_work_unit(unit)
  result = node['/work'].post(:work_unit => unit.to_json)
  unit.assign_to(self, JSON.parse(result)['pid'])
  touch && true
rescue RestClient::RequestFailed => e
  raise e unless e.http_code == 503 && e.http_body == Node::OVERLOADED_MESSAGE
  update_attribute(:busy, true) && false
rescue RestClient::Exception, Errno::ECONNREFUSED, Timeout::Error
  # Couldn't post to node, assume it's gone away.
  destroy && false
end

#to_json(opts = {}) ⇒ Object

The JSON representation of a NodeRecord includes its worker_pids.



89
90
91
92
93
94
# File 'lib/cloud_crowd/models/node_record.rb', line 89

def to_json(opts={})
  { 'host'    => host,
    'workers' => worker_pids,
    'status'  => display_status
  }.to_json
end

#urlObject

The URL at which this Node may be reached. TODO: Make sure that the host actually has externally accessible DNS.



63
64
65
# File 'lib/cloud_crowd/models/node_record.rb', line 63

def url
  @url ||= "http://#{host}:#{port}"
end

#worker_pidsObject

A list of the process ids of the workers currently being run by the Node.



79
80
81
# File 'lib/cloud_crowd/models/node_record.rb', line 79

def worker_pids
  work_units.all(:select => 'worker_pid').map(&:worker_pid)
end