class OmfEc::Group
Group
instance used in experiment script
@!attribute name [String] name of the resource @!attribute id [String] pubsub topic id of the resource @!attribute net_ifs
[Array] network interfaces defined to be added to group @!attribute members [Array] holding members to be added to group @!attribute apps [Array] holding applications to be added to group
Attributes
Public Class Methods
@param [String] name name of the group @param [Hash] opts
# File lib/omf_ec/group.rb, line 30 def initialize(name, opts = {}, &block) super() self.name = name self.id = "#{OmfEc.experiment.id}.#{self.name}" # Add empty holders for members, network interfaces, and apps self.net_ifs = [] self.members = {} self.app_contexts = [] self.execs = [] # To record group 2 group relationship @g_aliases = [] @resource_topics = {} OmfEc.subscribe_and_monitor(id, self, &block) end
Public Instance Methods
# File lib/omf_ec/group.rb, line 199 def addApplication(name, location = nil, &block) app_cxt = OmfEc::Context::AppContext.new(name,location,self) block.call(app_cxt) if block self.app_contexts << app_cxt end
Add a new Prototype
to the NodeSet associated with this Root Path
-
name = name of the
Prototype
to associate with the NodeSet of this Path -
params = optional, a
Hash
with the bindings to be passed on to the
Prototype
instance (see Prototype.instantiate
)
# File lib/omf_ec/group.rb, line 133 def addPrototype(name, params = nil) debug "Use prototype #{name}." p = OmfEc::Prototype[name] if p.nil? error "Unknown prototype '#{name}'" return end p.instantiate(self, params) end
Add existing resources to the group
Resources to be added could be a list of resources, groups, or the mixture of both.
# File lib/omf_ec/group.rb, line 71 def add_resource(*names) names.flatten! # When names is array of resource hash if !names.empty? && names[0].kind_of?(Hash) names.map! { |v| v['omf_id'] if v['type'] == 'node' }.compact! end synchronize do # Recording membership first, used for ALL_UP event names.each do |name| if (g = OmfEc.experiment.group(name))# resource to add is a group @members.merge!(g.members) @g_aliases << g else OmfEc.experiment.nodes << name unless OmfEc.experiment.nodes.include?(name) @members[name] = nil end end end end
# File lib/omf_ec/group.rb, line 47 def address(suffix = nil) t_id = suffix ? "#{self.id}_#{suffix.to_s}" : self.id OmfCommon.comm.string_to_topic_address(t_id) end
# File lib/omf_ec/group.rb, line 58 def associate_resource_topic(name, res_topic) self.synchronize do @resource_topics[name] = res_topic end end
# File lib/omf_ec/group.rb, line 52 def associate_topic(topic) self.synchronize do @topic = topic end end
Create a set of new resources and add them to the group
@param [String] name @param [Hash] opts to be used to create new resources
# File lib/omf_ec/group.rb, line 97 def create_resource(name, opts, &block) self.synchronize do raise ArgumentError, "Option :type is required for creating resource" if opts[:type].nil? # Make a deep copy of opts in case it contains structures of structures begin opts = Marshal.load ( Marshal.dump(opts.merge(hrn: name))) rescue => e raise "#{e.message} - Could not deep copy opts: '#{opts.inspect}'" end # Naming convention of child resource group #resource_group_name = "#{self.id}_#{opts[:type].to_s}" resource_group_name = self.address(opts[:type]) OmfEc.subscribe_and_monitor(resource_group_name) do |res_group| associate_resource_topic(opts[:type].to_s, res_group) # Send create message to group r_type = opts.delete(:type) @topic.create(r_type, opts.merge(membership: resource_group_name), assert: OmfEc.experiment.assertion) end end end
Create an application for the group and start it
# File lib/omf_ec/group.rb, line 151 def exec(command) name = SecureRandom.uuid self.synchronize do self.execs << name end create_resource(name, type: 'application', binary_path: command) e_name = "#{self.name}_application_#{name}_created" resource_group_name = self.address("application") def_event e_name do |state| state.find_all { |v| v[:hrn] == name && v[:membership] && v[:membership].include?(resource_group_name)}.size >= self.members.values.sort.uniq.size end on_event e_name do resources[type: 'application', name: name].state = :running end end
# File lib/omf_ec/group.rb, line 215 def method_missing(name, *args, &block) if name =~ /w(\d+)/ net = self.net_ifs.find { |v| v.conf[:if_name] == "wlan#{$1}" } if net.nil? net = OmfEc::Context::NetContext.new(:type => 'wlan', :if_name => "wlan#{$1}", :index => $1) self.net_ifs << net end net elsif name =~ /e(\d+)/ net = self.net_ifs.find { |v| v.conf[:if_name] == "eth#{$1}" } if net.nil? net = OmfEc::Context::NetContext.new(:type => 'net', :if_name => "eth#{$1}", :index => $1) self.net_ifs << net end net else super end end
@example
group('actor', 'node1', 'node2') do |g| g.net.w0.ip = '0.0.0.0' g.net.e0.ip = '0.0.0.1' end
# File lib/omf_ec/group.rb, line 210 def net self.net_ifs ||= [] self end
# File lib/omf_ec/group.rb, line 145 def resource_group(type) "#{self.id}_#{type.to_s}" end
# File lib/omf_ec/group.rb, line 64 def resource_topic(name) @resource_topics[name] end
@return [OmfEc::Context::GroupContext]
# File lib/omf_ec/group.rb, line 123 def resources OmfEc::Context::GroupContext.new(group: self) end
Start ONE application by name
# File lib/omf_ec/group.rb, line 173 def startApplication(app_name) if self.app_contexts.find { |v| v.name == app_name } resources[type: 'application', name: app_name].state = :running else warn "No application with name '#{app_name}' defined in group #{self.name}. Nothing to start" end end
Start ALL applications in the group
# File lib/omf_ec/group.rb, line 182 def startApplications if self.app_contexts.empty? warn "No applications defined in group #{self.name}. Nothing to start" else resources[type: 'application'].state = :running end end
Stop ALL applications in the group
# File lib/omf_ec/group.rb, line 191 def stopApplications if self.app_contexts.empty? warn "No applications defined in group #{self.name}. Nothing to stop" else resources[type: 'application'].state = :stopped end end