Name: simulation/lib/standalone.rb
| 1: | #!/usr/bin/ruby |
| 2: | require 'xml/smart' |
| 3: | require 'xmlsimple' |
| 4: | require 'riddl/client' |
| 5: | require 'json' |
| 6: | require 'chronic_duration' |
| 7: | require 'time' |
| 8: | require 'pp' |
| 9: | require File.expand_path(File.dirname(__FILE__) + '/expectations') |
| 10: | require File.expand_path(File.dirname(__FILE__) + '/result') |
| 11: | |
| 12: | $dir = File.dirname(__FILE__) + "/../instances/#{ARGV[0]}" |
| 13: | unless File.exists?($dir + "/model") |
| 14: | puts "This instance/simulation is not available!" |
| 15: | exit |
| 16: | end |
| 17: | |
| 18: | ### expected.txt |
| 19: | |
| 20: | s = Expectations.new($dir + "/model") |
| 21: | tree = s.tree |
| 22: | traces = s.traces |
| 23: | |
| 24: | expected = '' |
| 25: | expected << tree.to_s |
| 26: | |
| 27: | ctraces = traces.calculate.sort{|a,b| b.probability <=> a.probability} |
| 28: | ctraces.each_with_index do |t,i| |
| 29: | expected << "\n" |
| 30: | expected << "Trace #{i}: " << t.trace.inspect << "\n" |
| 31: | expected << "Expected Probability: #{"%0.2f" % t.probability}" << "\n" |
| 32: | expected << "Expected Duration:" << "\n" |
| 33: | expected << " Min.: #{ChronicDuration.output(t.min_time)}" << "\n" |
| 34: | expected << " Avg.: #{ChronicDuration.output(t.avg_time)}" << "\n" |
| 35: | expected << " Max.: #{ChronicDuration.output(t.max_time)}" << "\n" |
| 36: | end |
| 37: | File.write($dir + "/expectations.txt", expected) |
| 38: | |
| 39: | ### result.txt |
| 40: | |
| 41: | result = Result::askForInput("Offset",File.read(File.dirname(__FILE__) + "/../resources/offset.txt"),"Offset:") |
| 42: | meta = JSON.parse(File.read($dir + "/meta")) |
| 43: | meta['offset'] = result |
| 44: | File.write($dir + "/meta",JSON.generate(meta)) |
| 45: | |
| 46: | ### Move this to helpers.rb #forecast |
| 47: | ### workaround for now, as we don't have built in simulation |
| 48: | xmpp = Riddl::Client.interface('xmpp://[email protected]', ::File.dirname(__FILE__) + '/../simulation_gateway.xml', :jid => 'jü[email protected]', :pass => 'mangler') |
| 49: | |
| 50: | ### Simulation |
| 51: | resultoftraces = [] |
| 52: | meta = JSON.parse(File.read($dir + "/meta")) |
| 53: | ### each trace according to importance |
| 54: | ctraces.each_with_index do |ct,i| |
| 55: | ### each activity according to order |
| 56: | offset = meta['offset'].strip == '' ? 0 : ChronicDuration.parse(meta['offset']) |
| 57: | offset = 0 if offset.nil? |
| 58: | resultoftraces[i] = ResultTreeNode.new("◯","Start",nil,{},{},offset,offset,offset,0,0,0,100) |
| 59: | resulttreenode = resultoftraces[i] |
| 60: | XML::Smart.open($dir + '/endpoints').find('/xmlns:value/xmlns:*').each do |k| |
| 61: | resulttreenode.endpoints[k.qname.name] = k.text |
| 62: | end |
| 63: | |
| 64: | ct.trace.each do |a| |
| 65: | resulttreenode.each_leaf do |tn| |
| 66: | case a.type |
| 67: | when :manipulate |
| 68: | success, dataelements, endpoints = Result::manipulate(tn.dataelements,tn.endpoints,{},a) |
| 69: | if success |
| 70: | tn << ResultTreeNode.new(a.tid,"successfully executed script task #{a.to_s_nice}",nil,dataelements,endpoints,tn.start_min,tn.start_avg,tn.start_max,0,0,0,100) |
| 71: | else |
| 72: | tn << ResultTreeNode.new(a.tid,"failed to executed script task #{a.to_s_nice}",nil,tn.dataelements,tn.endpoints,tn.start_min,tn.start_avg,tn.start_max,0,0,0,100) |
| 73: | end |
| 74: | when :call |
| 75: | tnc = [] |
| 76: | a.endpoints.each_with_index do |ep,i| |
| 77: | ts = tn.start_min + tn.min |
| 78: | ta = tn.start_avg + tn.avg |
| 79: | tm = tn.start_max + tn.max |
| 80: | status, result = Result::forecast(xmpp,tn.dataelements,tn.endpoints,ep,a,ts,ta,tm) |
| 81: | if status == 200 |
| 82: | result.each do |res,det| |
| 83: | success, tde, tep = Result::manipulate(tn.dataelements,tn.endpoints,res,a) |
| 84: | if success |
| 85: | tnc << ResultTreeNode.new("#{a.tid}","successful forecast for task #{a.to_s_nice}",ep,tde,tep,ts,ta,tm,det[:min],det[:avg],det[:max],det[:prob]) |
| 86: | else |
| 87: | tnc << ResultTreeNode.new("#{a.tid}","unsuccessful forecast for task #{a.to_s_nice}",ep,tn.dataelements,tn.endpoints,ts,ta,tm,det[:min],det[:avg],det[:max],det[:prob]) |
| 88: | end |
| 89: | end |
| 90: | else |
| 91: | tnc << ResultTreeNode.new("#{a.tid}","forecast for task #{a.to_s_nice} failed",ep,tn.dataelements,tn.endpoints,ts,ta,tm,a.min,a.avg,a.max,100) |
| 92: | end |
| 93: | end |
| 94: | ### Remove duplicate results, even when they come from different partners, for optimum performance |
| 95: | ### Results are unique, when they produce different dataflow, or have different probabilities to occur |
| 96: | tnc = tnc.reduce([]) do |memo,tc| |
| 97: | success = false |
| 98: | memo.each do |e| |
| 99: | if e.dataelements == tc.dataelements && e.prob == tc.prob |
| 100: | e.endpoint << ", #{tc.endpoint}" |
| 101: | success = true |
| 102: | end |
| 103: | end |
| 104: | memo << tc unless success |
| 105: | memo |
| 106: | end |
| 107: | tnc.each { |tc| tn << tc } |
| 108: | end |
| 109: | |
| 110: | ### write temporary output to result.txt |
| 111: | obtained = "" |
| 112: | resultoftraces.each_with_index do |t,i| |
| 113: | obtained << "\n" |
| 114: | obtained << "Trace #{i}: #{ctraces[0].trace.to_s}\n\n" |
| 115: | obtained << t.to_s |
| 116: | end |
| 117: | File.write($dir + "/result.txt", obtained) |
| 118: | |
| 119: | end |
| 120: | end |
| 121: | end |
| 122: | |
| 123: | Result::finish |
