Class: OmfEc::Experiment
- Inherits:
-
Object
- Object
- OmfEc::Experiment
- Includes:
- MonitorMixin, Singleton
- Defined in:
- lib/omf_ec/experiment.rb
Overview
Experiment class to hold relevant state information
Defined Under Namespace
Classes: MetaData
Instance Attribute Summary collapse
-
#app_definitions ⇒ Object
Returns the value of attribute app_definitions.
-
#cmdline_properties ⇒ Object
Returns the value of attribute cmdline_properties.
-
#groups ⇒ Object
readonly
Returns the value of attribute groups.
-
#name ⇒ Object
Returns the value of attribute name.
-
#nodes ⇒ Object
Returns the value of attribute nodes.
-
#oml_uri ⇒ Object
Returns the value of attribute oml_uri.
-
#property ⇒ Object
Returns the value of attribute property.
-
#show_graph ⇒ Object
Returns the value of attribute show_graph.
-
#state ⇒ Object
readonly
Returns the value of attribute state.
-
#sub_groups ⇒ Object
readonly
Returns the value of attribute sub_groups.
Class Method Summary collapse
- .disconnect ⇒ Object
-
.done ⇒ Object
Disconnect communicator, try to delete any XMPP affiliations.
-
.leave_memberships ⇒ Object
Ask the resources which joined the groups I created to leave.
- .start ⇒ Object
Instance Method Summary collapse
- #add_event(name, trigger) ⇒ Object
- #add_group(group) ⇒ Object
- #add_or_update_resource_state(name, opts = {}) ⇒ Object (also: #add_resource)
- #add_property(name, value = nil, description = nil) ⇒ Object
- #add_sub_group(name) ⇒ Object
- #all_groups?(&block) ⇒ Boolean
-
#archive_oedl(script_name) ⇒ Object
Archive OEDL content to OML db.
- #each_group(&block) ⇒ Object
- #event(name) ⇒ Object
- #group(name) ⇒ Object
-
#groups_by_res(res_addr) ⇒ Object
Find all groups a given resource belongs to.
-
#id ⇒ Object
Unique experiment id.
-
#initialize ⇒ Experiment
constructor
A new instance of Experiment.
- #log_metadata(key, value, domain = 'sys') ⇒ Object
- #mp_table_names ⇒ Object
-
#process_events ⇒ Object
Parsing user defined events, checking conditions against internal state, and execute callbacks if triggered.
- #resource_by_hrn(hrn) ⇒ Object
- #resource_state(address) ⇒ Object (also: #resource)
- #sub_group(name) ⇒ Object
Constructor Details
#initialize ⇒ Experiment
Returns a new instance of Experiment.
32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/omf_ec/experiment.rb', line 32 def initialize super @id = Time.now.utc.iso8601(3) @state ||= [] #TODO: we need to keep history of all the events and not ovewrite them @groups ||= [] @nodes ||= [] @events ||= [] @app_definitions ||= Hash.new @sub_groups ||= [] @cmdline_properties ||= Hash.new @show_graph = false end |
Instance Attribute Details
#app_definitions ⇒ Object
Returns the value of attribute app_definitions.
19 20 21 |
# File 'lib/omf_ec/experiment.rb', line 19 def app_definitions @app_definitions end |
#cmdline_properties ⇒ Object
Returns the value of attribute cmdline_properties.
19 20 21 |
# File 'lib/omf_ec/experiment.rb', line 19 def cmdline_properties @cmdline_properties end |
#groups ⇒ Object (readonly)
Returns the value of attribute groups.
20 21 22 |
# File 'lib/omf_ec/experiment.rb', line 20 def groups @groups end |
#name ⇒ Object
Returns the value of attribute name.
19 20 21 |
# File 'lib/omf_ec/experiment.rb', line 19 def name @name end |
#nodes ⇒ Object
Returns the value of attribute nodes.
19 20 21 |
# File 'lib/omf_ec/experiment.rb', line 19 def nodes @nodes end |
#oml_uri ⇒ Object
Returns the value of attribute oml_uri.
19 20 21 |
# File 'lib/omf_ec/experiment.rb', line 19 def oml_uri @oml_uri end |
#property ⇒ Object
Returns the value of attribute property.
19 20 21 |
# File 'lib/omf_ec/experiment.rb', line 19 def property @property end |
#show_graph ⇒ Object
Returns the value of attribute show_graph.
19 20 21 |
# File 'lib/omf_ec/experiment.rb', line 19 def show_graph @show_graph end |
#state ⇒ Object (readonly)
Returns the value of attribute state.
20 21 22 |
# File 'lib/omf_ec/experiment.rb', line 20 def state @state end |
#sub_groups ⇒ Object (readonly)
Returns the value of attribute sub_groups.
20 21 22 |
# File 'lib/omf_ec/experiment.rb', line 20 def sub_groups @sub_groups end |
Class Method Details
.disconnect ⇒ Object
227 228 229 230 231 232 233 234 |
# File 'lib/omf_ec/experiment.rb', line 227 def disconnect info "Disconnecting in 5 sec from experiment: #{OmfEc.experiment.id}" info "Run the EC again to reattach" OmfCommon.el.after(5) do OmfCommon.comm.disconnect OmfCommon.eventloop.stop end end |
.done ⇒ Object
Disconnect communicator, try to delete any XMPP affiliations
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/omf_ec/experiment.rb', line 203 def done info "Experiment: #{OmfEc.experiment.id} finished" info "Release applications and network interfaces" info "Exit in 15 seconds..." OmfCommon.el.after(10) do allGroups do |g| g.resources[type: 'application'].release unless g.app_contexts.empty? g.resources[type: 'net'].release unless g.net_ifs.find_all { |v| v.conf[:type] == 'net' }.empty? g.resources[type: 'wlan'].release unless g.net_ifs.find_all { |v| v.conf[:type] == 'wlan' }.empty? g.resources.membership = { leave: g.address } end OmfCommon.el.after(4) do info "OMF Experiment Controller #{OmfEc::VERSION} - Exit." OmfCommon.el.after(1) do OmfCommon.comm.disconnect OmfCommon.eventloop.stop end end end OmfEc.experiment.("state", "finished") end |
.leave_memberships ⇒ Object
Ask the resources which joined the groups I created to leave
255 256 257 258 259 |
# File 'lib/omf_ec/experiment.rb', line 255 def leave_memberships all_groups do |g| g.resources.membership = { leave: g.address } end end |
.start ⇒ Object
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/omf_ec/experiment.rb', line 236 def start info "Experiment: #{OmfEc.experiment.id} starts" OmfEc.experiment.("state", "running") allGroups do |g| g.members.each do |key, value| OmfEc.subscribe_and_monitor(key) do |res| info "Configure '#{key}' to join '#{g.name}'" g.synchronize do g.members[key] = res.address end res.configure(membership: g.address, :res_index => OmfEc.experiment.nodes.index(key)) end end end end |
Instance Method Details
#add_event(name, trigger) ⇒ Object
147 148 149 150 151 152 153 |
# File 'lib/omf_ec/experiment.rb', line 147 def add_event(name, trigger) self.synchronize do warn "Event '#{name}' has already been defined. Overwriting it now." if event(name) @events.delete_if { |e| e[:name] == name } @events << { name: name, trigger: trigger, aliases: [] } end end |
#add_group(group) ⇒ Object
124 125 126 127 128 129 |
# File 'lib/omf_ec/experiment.rb', line 124 def add_group(group) self.synchronize do raise ArgumentError, "Expect Group object, got #{group.inspect}" unless group.kind_of? OmfEc::Group @groups << group unless group(group.name) end end |
#add_or_update_resource_state(name, opts = {}) ⇒ Object Also known as: add_resource
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/omf_ec/experiment.rb', line 65 def add_or_update_resource_state(name, opts = {}) self.synchronize do res = resource_state(name) if res opts.each do |key, value| if value.class == Array # Merge array values res[key] ||= [] res[key] += value res[key].uniq! elsif value.kind_of? Hash # Merge hash values res[key] ||= {} res[key].merge(value) else # Overwrite otherwise res[key] = value end end else info "Newly discovered resource >> #{name}" res = Hashie::Mash.new({ address: name }).merge(opts) @state << res # Re send membership configure planned_groups = groups_by_res(res[:address]) unless planned_groups.empty? OmfEc.subscribe_and_monitor(name) do |res| info "Config #{name} to join #{planned_groups.map(&:name).join(', ')}" res.configure(membership: planned_groups.map(&:address)) end end end end end |
#add_property(name, value = nil, description = nil) ⇒ Object
49 50 51 52 53 |
# File 'lib/omf_ec/experiment.rb', line 49 def add_property(name, value = nil, description = nil) override_value = @cmdline_properties[name.to_s.to_sym] value = override_value unless override_value.nil? ExperimentProperty.create(name, value, description) end |
#add_sub_group(name) ⇒ Object
114 115 116 117 118 |
# File 'lib/omf_ec/experiment.rb', line 114 def add_sub_group(name) self.synchronize do @sub_groups << name unless @sub_groups.include?(name) end end |
#all_groups?(&block) ⇒ Boolean
139 140 141 |
# File 'lib/omf_ec/experiment.rb', line 139 def all_groups?(&block) !groups.empty? && groups.all? { |g| block ? block.call(g) : g } end |
#archive_oedl(script_name) ⇒ Object
Archive OEDL content to OML db
192 193 194 195 196 197 198 |
# File 'lib/omf_ec/experiment.rb', line 192 def archive_oedl(script_name) ( script_name, Base64.encode64(Zlib::Deflate.deflate(File.read(script_name))), "oedl_content" ) end |
#each_group(&block) ⇒ Object
131 132 133 134 135 136 137 |
# File 'lib/omf_ec/experiment.rb', line 131 def each_group(&block) if block groups.each { |g| block.call(g) } else groups end end |
#event(name) ⇒ Object
143 144 145 |
# File 'lib/omf_ec/experiment.rb', line 143 def event(name) @events.find { |v| v[:name] == name || v[:aliases].include?(name) } end |
#group(name) ⇒ Object
120 121 122 |
# File 'lib/omf_ec/experiment.rb', line 120 def group(name) groups.find { |v| v.name == name } end |
#groups_by_res(res_addr) ⇒ Object
Find all groups a given resource belongs to
106 107 108 |
# File 'lib/omf_ec/experiment.rb', line 106 def groups_by_res(res_addr) groups.find_all { |g| g.members.values.include?(res_addr) } end |
#id ⇒ Object
Unique experiment id
156 157 158 |
# File 'lib/omf_ec/experiment.rb', line 156 def id @name || @id end |
#log_metadata(key, value, domain = 'sys') ⇒ Object
186 187 188 189 |
# File 'lib/omf_ec/experiment.rb', line 186 def (key, value, domain = 'sys') #MetaData.inject_metadata(key.to_s, value.to_s) MetaData.inject(domain.to_s, key.to_s, value.to_s) end |
#mp_table_names ⇒ Object
178 179 180 181 182 183 184 |
# File 'lib/omf_ec/experiment.rb', line 178 def mp_table_names {}.tap do |m_t_n| groups.map(&:app_contexts).flatten.map(&:mp_table_names).each do |v| m_t_n.merge!(v) end end end |
#process_events ⇒ Object
Parsing user defined events, checking conditions against internal state, and execute callbacks if triggered
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/omf_ec/experiment.rb', line 161 def process_events self.synchronize do @events.find_all { |v| v[:callbacks] && !v[:callbacks].empty? }.each do |event| if event[:trigger].call(@state) @events.delete(event) if event[:consume_event] event_names = ([event[:name]] + event[:aliases]).join(', ') info "Event triggered: '#{event_names}'" # Last in first serve callbacks event[:callbacks].reverse.each do |callback| callback.call end end end end end |
#resource_by_hrn(hrn) ⇒ Object
61 62 63 |
# File 'lib/omf_ec/experiment.rb', line 61 def resource_by_hrn(hrn) @state.find { |v| v[:hrn].to_s == hrn.to_s } end |
#resource_state(address) ⇒ Object Also known as: resource
55 56 57 |
# File 'lib/omf_ec/experiment.rb', line 55 def resource_state(address) @state.find { |v| v[:address].to_s == address.to_s } end |
#sub_group(name) ⇒ Object
110 111 112 |
# File 'lib/omf_ec/experiment.rb', line 110 def sub_group(name) @sub_groups.find { |v| v == name } end |