class Symian::Simulation
Constants
- ATTRIBUTES
Public Class Methods
new(configuration, performance_analyzer, trace=TraceCollector.new(:memory))
click to toggle source
# File lib/symian/simulation.rb, line 19 def initialize(configuration, performance_analyzer, trace=TraceCollector.new(:memory)) @configuration = configuration # setup performance analyzer and simulation trace @performance_analyzer = performance_analyzer @trace = trace # setup simulation start and current time @current_time = @start_time = @configuration.start_time # create support groups @support_groups = {} @configuration.support_groups.each do |name,conf| @support_groups[name] = SupportGroup.new(name, self, conf[:work_time], conf[:operators]) end # create transition matrix @transition_matrix = TransitionMatrix.new(@configuration.transition_matrix) # create event queue @event_queue = SortedArray.new end
Public Instance Methods
new_event(type, data, time, destination)
click to toggle source
# File lib/symian/simulation.rb, line 43 def new_event(type, data, time, destination) @event_queue << Event.new(type, data, time, destination) end
now()
click to toggle source
# File lib/symian/simulation.rb, line 48 def now @current_time end
run()
click to toggle source
# File lib/symian/simulation.rb, line 53 def run # initialize support groups @support_groups.values.each do |sg| sg.initialize_at(@configuration.start_time) end # generate first incident ig = IncidentGenerator.new(self, @configuration.incident_generation) ig.generate # schedule end of simulation unless @configuration.end_time.nil? # puts "Simulation ends at: #{@configuration.end_time}" new_event(Event::ET_END_OF_SIMULATION, nil, @configuration.end_time, nil) end # calculate warmup threshold warmup_threshold = @configuration.start_time + @configuration.warmup_duration @incidents_being_worked_on ||= [] # launch simulation until @event_queue.empty? e = @event_queue.shift # sanity check on simulation time flow if @current_time > e.time raise 'Error: simulation time inconsistency for event ' + "e.type=#{e.type} @current_time=#{@current_time}, e.time=#{e.time}" end @current_time = e.time #Trace.new_event e case e.type when Event::ET_INCIDENT_ARRIVAL sg_name = @transition_matrix.escalation('In') sg = @support_groups[sg_name] sg.new_incident(e.data, e.time) @incidents_being_worked_on << e.data # generate next incident ig.generate # TODO: pinpoint instant for calculation of time spent in enqueued state when Event::ET_INCIDENT_ASSIGNMENT # TODO: implement calculation of time spent in suspended state when Event::ET_OPERATOR_ACTIVITY_STARTS when Event::ET_OPERATOR_ACTIVITY_FINISHES sg = @support_groups[e.destination] sg.operator_finished_working(e.data[0], e.time) when Event::ET_INCIDENT_RESCHEDULING sg = @support_groups[e.destination] sg.schedule_incident_for_reassignment(e.data[0], e.data[1], e.time) # TODO: pinpoint instant for calculation of time spent in suspended state when Event::ET_INCIDENT_ESCALATION inc = e.data sg_name = @transition_matrix.escalation(e.destination) if sg_name == "Out" inc.closure_time = e.time # remove incident from list of incidents being worked on and add it to trace @incidents_being_worked_on.delete(inc) @trace.record_incidents(inc) else sg = @support_groups[sg_name] sg.new_incident(inc, e.time) end when Event::ET_OPERATOR_LEAVING sg = @support_groups[e.destination] sg.operator_going_home(e.data, e.time) when Event::ET_OPERATOR_RETURNING sg = @support_groups[e.destination] sg.operator_arrived_at_work(e.data, e.time) when Event::ET_SUPPORT_GROUP_QUEUE_SIZE_CHANGE when Event::ET_END_OF_SIMULATION break end end # save trace file @trace.save_and_close kpis = @performance_analyzer.calculate_kpis(@trace) kpis.merge(incidents_being_worked_on: @incidents_being_worked_on.size) end