Module: OmfEc::DSL

Defined in:
lib/omf_ec/dsl.rb

Overview

DSL methods to be used for OEDL scripts

Defined Under Namespace

Classes: OEDLArgumentException, OEDLCommandException, OEDLException, OEDLUnknownProperty

Instance Method Summary collapse

Instance Method Details

#after(time, &block) ⇒ Object

Use EM timer to execute after certain time

Examples:

do something after 2 seconds


after 2.seconds { 'do something' }


57
58
59
# File 'lib/omf_ec/dsl.rb', line 57

def after(time, &block)
  OmfCommon.eventloop.after(time, &block)
end

#alias_event(new_name, name) ⇒ Object

Create an alias name of an event



198
199
200
201
202
203
204
# File 'lib/omf_ec/dsl.rb', line 198

def alias_event(new_name, name)
  unless (event = OmfEc.experiment.event(name))
    raise RuntimeError, "Can not create alias for Event '#{name}' which is not defined"
  else
    event[:aliases] << new_name
  end
end

#all_equal(array, value = nil, &block) ⇒ Object

Check if all elements in array equal the value provided



173
174
175
176
177
178
179
180
181
182
183
# File 'lib/omf_ec/dsl.rb', line 173

def all_equal(array, value = nil, &block)
  if array.empty?
    false
  else
    if value
      array.all? { |v| v.to_s == value.to_s }
    else
      array.all?(&block)
    end
  end
end

#all_groups(&block) ⇒ Object Also known as: all_nodes!

Iterator for all defined groups



120
121
122
# File 'lib/omf_ec/dsl.rb', line 120

def all_groups(&block)
  OmfEc.experiment.each_group(&block)
end

#all_groups?(&block) ⇒ Boolean

Returns:

  • (Boolean)


124
125
126
# File 'lib/omf_ec/dsl.rb', line 124

def all_groups?(&block)
  OmfEc.experiment.all_groups?(&block)
end

#def_application(name, &block) ⇒ Object



70
71
72
73
74
# File 'lib/omf_ec/dsl.rb', line 70

def def_application(name, &block)
  app_def = OmfEc::AppDefinition.new(name)
  OmfEc.experiment.app_definitions[name] = app_def
  block.call(app_def) if block
end

#def_event(name, &trigger) ⇒ Object

Define an event

Raises:

  • (ArgumentError)


192
193
194
195
# File 'lib/omf_ec/dsl.rb', line 192

def def_event(name, &trigger)
  raise ArgumentError, 'Need a trigger callback' if trigger.nil?
  OmfEc.experiment.add_event(name, trigger)
end

#def_graph(name = nil, &block) ⇒ Object

Define a new graph widget showing experiment related measurements to be be used in a LabWiki column.

The block is called with an instance of the ‘LabWiki::OMFBridge::GraphDescription’ class. See that classes’ documentation on the methods supported.

Parameters:

  • name (defaults to: nil)

    short/easy to remember name for this graph



224
225
226
227
228
229
230
# File 'lib/omf_ec/dsl.rb', line 224

def def_graph(name = nil, &block)
  if OmfEc.experiment.show_graph
    gd = OmfEc::Graph::GraphDescription.create(name)
    block.call(gd)
    gd._report
  end
end

#def_group(name, *members, &block) ⇒ Object

Define a group, create a pubsub topic for the group

Examples:

add resource ‘a’, ‘b’ to group ‘My_Pinger’


defGroup('My_Pinger', 'a', 'b') do |g|
  g.addApplication("ping") do |app|
    app.setProperty('target', 'mytestbed.net')
    app.setProperty('count', 3)
  end
end

# Or pass resources as an array

res_array = ['a', 'b']

defGroup('My_Pinger', res_array) do |g|
  g.addApplication("ping") do |app|
    app.setProperty('target', 'mytestbed.net')
    app.setProperty('count', 3)
  end
end

Parameters:

  • name (String)

    name of the group



100
101
102
103
104
105
106
# File 'lib/omf_ec/dsl.rb', line 100

def def_group(name, *members, &block)
  group = OmfEc::Group.new(name)
  OmfEc.experiment.add_group(group)
  group.add_resource(*members)

  block.call(group) if block
end

#def_property(name, default_value, description = nil, type = nil) ⇒ Object

Define an experiment property which can be used to bind to application and other properties. Changing an experiment property should also change the bound properties, or trigger commands to change them.

Parameters:

  • name

    of property

  • default_value

    for this property

  • description (defaults to: nil)

    short text description of this property

  • type (defaults to: nil)

    of property



149
150
151
# File 'lib/omf_ec/dsl.rb', line 149

def def_property(name, default_value, description = nil, type = nil)
  OmfEc.experiment.add_property(name, default_value, description)
end

#deprecated_load_oedl(location) ⇒ Object



292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/omf_ec/dsl.rb', line 292

def deprecated_load_oedl(location)
  warn "Loading OEDL Library using DEPRECATED syntax. Please use proper URI syntax"
  begin
    require location
    info "Loaded built-in OEDL library '#{location}'"
  rescue LoadError
    begin
      file = Tempfile.new("oedl-#{Time.now.to_i}")
      open(location) { |io| file.write(io.read) }
      file.close
      OmfEc.experiment.archive_oedl(file.path)
      load(file.path)
      file.unlink
      info "Loaded external OEDL library '#{location}'"
    rescue Exception => e
      error "Fail loading external OEDL library '#{location}': #{e}"
    end
  rescue Exception => e
    error "Fail loading built-in OEDL library '#{location}': #{e}"
  end
end

#done!Object Also known as: done

Exit the experiment

See Also:



133
134
135
# File 'lib/omf_ec/dsl.rb', line 133

def done!
  OmfEc::Experiment.done
end

#ensure_property(name, default_value, description = nil, type = nil) ⇒ Object

Check if a property exist, if not then define it Take the same parameter as def_property



161
162
163
164
165
166
167
# File 'lib/omf_ec/dsl.rb', line 161

def ensure_property(name, default_value, description = nil, type = nil)
  begin
    property[name]
  rescue
    def_property(name, default_value, description, type)
  end
end

#every(time, &block) ⇒ Object

Use EM periodic timer to execute after certain time

Examples:

do something every 2 seconds


every 2.seconds { 'do something' }


66
67
68
# File 'lib/omf_ec/dsl.rb', line 66

def every(time, &block)
  OmfCommon.eventloop.every(time, &block)
end

#group(name, &block) ⇒ Object

Get a group instance

Parameters:

  • name (String)

    name of the group

Raises:

  • (RuntimeError)


111
112
113
114
115
116
117
# File 'lib/omf_ec/dsl.rb', line 111

def group(name, &block)
  group = OmfEc.experiment.group(name)
  raise RuntimeError, "Group #{name} not found" if group.nil?

  block.call(group) if block
  group
end

#load_oedl(location, opts = {}) ⇒ Object

Load an additional OEDL script referenced by a URI

The supported URI schemes are:

  • file:///foo/bar.rb , which loads the file located at ‘/foo/bar.rb’ on the local filesystem

  • system:///foo/bar.rb , which loads the file located at ‘foo/bar.rb’ in the default Ruby path of this EC

  • foo.com/bar.rb , which loads the file located at the URL ‘foo.com/bar.rb

If an optional has of key/value is provided, then define an OMF Experiment Property for each keys and assigne them the values.

Parameters:

  • uri

    URI for the OEDL script to load

  • opts (defaults to: {})

    optional hash of key/values for extra Experiment Property to define



245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
# File 'lib/omf_ec/dsl.rb', line 245

def load_oedl(location, opts = {})
  begin
    u = URI(location.downcase)
  rescue Exception => e
    warn "Unsupported OEDL library location '#{location}'"
    return
  end

  # Define the additional properties from opts
  opts.each { |k,v| def_property(k, v,) }

  # Keep the old syntax around for a while, warn users to use the new URI syntax
  # TODO: remove this in a couple of EC versions
  if u.scheme.nil? || u.scheme.empty?
    deprecated_load_oedl(location)
    return
  end

  # Find out which type of location this is and deal with it accordingly
  case u.scheme.downcase.to_sym
  when :system
    begin
      u.path[0]='' # get rid of first '/'
      require u.path
      info "Loaded built-in OEDL library '#{location}'"
    rescue Exception => e
      error "Fail loading built-in OEDL library '#{location}': #{e}"
    end
  when :file, :http, :https
    begin
      file = Tempfile.new("oedl-#{Time.now.to_i}")
      # see: http://stackoverflow.com/questions/7578898
      open(u.to_s.sub(%r{^file:}, '')) { |io| file.write(io.read) }
      file.close
      OmfEc.experiment.archive_oedl(file.path)
      load(file.path)
      file.unlink
      info "Loaded external OEDL library '#{location}'"
    rescue Exception => e
      error "Fail loading external OEDL library '#{location}': #{e}"
    end
  else
    warn "Unsupported scheme for OEDL library location '#{location}'"
    return
  end
end

#on_event(name, consume_event = true, &callback) ⇒ Object

Define an event callback



207
208
209
210
211
212
213
214
215
# File 'lib/omf_ec/dsl.rb', line 207

def on_event(name, consume_event = true, &callback)
  unless (event = OmfEc.experiment.event(name))
    raise RuntimeError, "Event '#{name}' not defined"
  else
    event[:callbacks] ||= []
    event[:callbacks] << callback
    event[:consume_event] = consume_event
  end
end

#one_equal(array, value) ⇒ Object

Check if any elements in array equals the value provided



187
188
189
# File 'lib/omf_ec/dsl.rb', line 187

def one_equal(array, value)
  !array.any? ? false : array.any? { |v| v.to_s == value.to_s }
end

#propertyObject Also known as: prop

Return the context for setting experiment wide properties



154
155
156
# File 'lib/omf_ec/dsl.rb', line 154

def property
  return OmfEc.experiment.property
end