use of desmoj.core.simulator.TimeSpan in project scylla by bptlab.
the class BPMNStartEvent method eventRoutine.
@Override
public void eventRoutine(ProcessInstance processInstance) throws SuspendExecution {
super.eventRoutine(processInstance);
SimulationModel model = (SimulationModel) getModel();
ProcessModel processModel = processInstance.getProcessModel();
Map<EventDefinitionType, Map<String, String>> definitions = processModel.getEventDefinitions().get(nodeId);
Set<String> messages = new HashSet<String>();
for (EventDefinitionType definition : definitions.keySet()) {
if (definition == EventDefinitionType.MESSAGE) {
String message = "Message Start Event: " + displayName;
messages.add(message);
} else if (definition == EventDefinitionType.TIMER) {
String message = "Timer Start Event: " + displayName;
messages.add(message);
} else if (definition == EventDefinitionType.CONDITIONAL) {
String message = "Conditional Start Event: " + displayName;
messages.add(message);
} else if (definition == EventDefinitionType.SIGNAL) {
String message = "Signal Start Event: " + displayName;
messages.add(message);
}
}
if (messages.isEmpty()) {
String message = "None Start Event: " + displayName;
messages.add(message);
}
for (String message : messages) {
sendTraceNote(message);
}
try {
// get next node(s)
Set<Integer> idsOfNextNodes = processModel.getIdsOfNextNodes(nodeId);
// BPMN start event must not have more than successor
if (idsOfNextNodes.size() != 1) {
throw new ScyllaValidationException("Start event " + nodeId + " does not have 1 successor, but " + idsOfNextNodes.size() + ".");
}
Integer nextNodeId = idsOfNextNodes.iterator().next();
List<ScyllaEvent> events = SimulationUtils.createEventsForNextNode(this, pSimComponents, processInstance, nextNodeId);
// next event occurs immediately after start event
TimeSpan timeSpan = new TimeSpan(0);
for (ScyllaEvent event : events) {
int index = getNewEventIndex();
nextEventMap.put(index, event);
timeSpanToNextEventMap.put(index, timeSpan);
}
// unless current one is BPMN timer event with timerDuration
BPMNStartEventPluggable.runPlugins(this, processInstance);
scheduleNextEvents();
} catch (NodeNotFoundException | ScyllaValidationException | ScyllaRuntimeException e) {
DebugLogger.error(e.getMessage());
e.printStackTrace();
SimulationUtils.abort(model, processInstance, nodeId, traceIsOn());
return;
}
}
use of desmoj.core.simulator.TimeSpan in project scylla by bptlab.
the class ProcessInstanceGenerationEvent method eventRoutine.
// TODO XSD validation
// TODO fixed cost per task
@Override
public void eventRoutine(ProcessInstance processInstance) throws SuspendExecution {
this.processInstance = processInstance;
SimulationModel model = (SimulationModel) getModel();
TimeInstant currentSimulationTime = model.presentTime();
TimeUnit timeUnit = DateTimeUtils.getReferenceTimeUnit();
long currentTime = currentSimulationTime.getTimeRounded(timeUnit);
if (currentTime >= endTimeRelativeToGlobalStart) {
// if the end time is reached
return;
}
boolean showInTrace = traceIsOn();
String name = getName();
ProcessSimulationComponents desmojObjects = model.getDesmojObjectsMap().get(processId);
ProcessModel processModel = desmojObjects.getProcessModel();
try {
Integer startNodeId = processModel.getStartNode();
timeSpanToStartEvent = new TimeSpan(0);
ProcessInstanceGenerationEventPluggable.runPlugins(this, processInstance);
BPMNStartEvent event = new BPMNStartEvent(model, name, currentSimulationTime, desmojObjects, processInstance, startNodeId);
int processInstanceId = desmojObjects.incrementProcessInstancesStarted();
// schedule next process instance start event
if (processInstanceId <= desmojObjects.getSimulationConfiguration().getNumberOfProcessInstances()) {
double duration = desmojObjects.getDistributionSample(startNodeId);
TimeUnit unit = desmojObjects.getDistributionTimeUnit(startNodeId);
ProcessInstance nextProcessInstance = new ProcessInstance(model, processModel, processInstanceId, showInTrace);
timeSpanToNextProcessInstance = new TimeSpan(duration, unit);
ProcessInstanceGenerationEvent nextEvent = new ProcessInstanceGenerationEvent(model, processId, endTimeRelativeToGlobalStart, showInTrace);
nextEvent.schedule(nextProcessInstance, timeSpanToNextProcessInstance);
}
// schedule for start of simulation
event.schedule(processInstance, timeSpanToStartEvent);
} catch (NodeNotFoundException | MultipleStartNodesException | NoStartNodeException | ScyllaRuntimeException e) {
DebugLogger.error(e.getMessage());
e.printStackTrace();
DebugLogger.log("Error during instantiation of process model " + processModel.getId() + ".");
// no node initialized, use zero
int nodeId = 0;
SimulationUtils.abort(model, processInstance, nodeId, showInTrace);
}
}
use of desmoj.core.simulator.TimeSpan in project scylla by bptlab.
the class TaskBeginEvent method eventRoutine.
@Override
public void eventRoutine(ProcessInstance processInstance) throws SuspendExecution {
super.eventRoutine(processInstance);
SimulationModel model = (SimulationModel) getModel();
TimeInstant currentSimulationTime = model.presentTime();
ProcessModel processModel = processInstance.getProcessModel();
ProcessModel subProcess = processModel.getSubProcesses().get(nodeId);
TaskType type = processModel.getTasks().get(nodeId);
String message = null;
if (subProcess != null) {
message = "Begin Subprocess: " + displayName;
} else if (type == TaskType.DEFAULT) {
message = "Begin Default Task: " + displayName;
} else if (type == TaskType.SERVICE) {
message = "Begin Service Task: " + displayName;
} else if (type == TaskType.SEND) {
message = "Begin Send Task: " + displayName;
} else if (type == TaskType.RECEIVE) {
message = "Begin Receive Task: " + displayName;
} else if (type == TaskType.USER) {
message = "Begin User Task: " + displayName;
} else if (type == TaskType.MANUAL) {
message = "Begin Manual Task: " + displayName;
} else if (type == TaskType.BUSINESS_RULE) {
message = "Begin Business Rule: " + displayName;
} else if (type == TaskType.SCRIPT) {
message = "Begin Script Task: " + displayName;
} else {
SimulationUtils.sendElementNotSupportedTraceNote(model, processModel, displayName, nodeId);
SimulationUtils.abort(model, processInstance, nodeId, traceIsOn());
return;
}
sendTraceNote(message);
try {
double duration = pSimComponents.getDistributionSample(nodeId);
TimeUnit unit = pSimComponents.getDistributionTimeUnit(nodeId);
ScyllaEvent event = new TaskTerminateEvent(model, source, currentSimulationTime, pSimComponents, processInstance, nodeId);
TimeSpan timeSpan = new TimeSpan(duration, unit);
ResourceObjectTuple tuple = processInstance.getAssignedResources().get(source);
TimeInstant nextEventTime = DateTimeUtils.getTaskTerminationTime(timeSpan, currentSimulationTime, tuple, event);
timeSpan = new TimeSpan(nextEventTime.getTimeAsDouble() - currentSimulationTime.getTimeAsDouble());
int index = getNewEventIndex();
nextEventMap.put(index, event);
timeSpanToNextEventMap.put(index, timeSpan);
TaskBeginEventPluggable.runPlugins(this, processInstance);
scheduleNextEvents();
} catch (ScyllaRuntimeException e) {
System.err.println(e.getMessage());
e.printStackTrace();
SimulationUtils.abort(model, processInstance, nodeId, traceIsOn());
return;
}
}
use of desmoj.core.simulator.TimeSpan in project scylla by bptlab.
the class TaskEnableEvent method eventRoutine.
@Override
public void eventRoutine(ProcessInstance processInstance) throws SuspendExecution {
super.eventRoutine(processInstance);
SimulationModel model = (SimulationModel) getModel();
source = getName();
TimeInstant currentSimulationTime = model.presentTime();
ProcessModel processModel = processInstance.getProcessModel();
// int processInstanceId = processInstance.getId();
ProcessModel subProcess = processModel.getSubProcesses().get(nodeId);
TaskType type = processModel.getTasks().get(nodeId);
String message = null;
if (subProcess != null) {
message = "Enable Subprocess: " + displayName;
} else if (type == TaskType.DEFAULT) {
message = "Enable Default Task: " + displayName;
} else if (type == TaskType.SERVICE) {
message = "Enable Service Task: " + displayName;
} else if (type == TaskType.SEND) {
message = "Enable Send Task: " + displayName;
} else if (type == TaskType.RECEIVE) {
message = "Enable Receive Task: " + displayName;
} else if (type == TaskType.USER) {
message = "Enable User Task: " + displayName;
} else if (type == TaskType.MANUAL) {
message = "Enable Manual Task: " + displayName;
} else if (type == TaskType.BUSINESS_RULE) {
message = "Enable Business Rule: " + displayName;
} else if (type == TaskType.SCRIPT) {
message = "Enable Script Task: " + displayName;
} else {
SimulationUtils.sendElementNotSupportedTraceNote(model, processModel, displayName, nodeId);
SimulationUtils.abort(model, processInstance, nodeId, traceIsOn());
return;
}
sendTraceNote(message);
try {
// poll available resources and if not available, put TaskBeginEvent on hold
ScyllaEvent event = new TaskBeginEvent(model, source, currentSimulationTime, pSimComponents, processInstance, nodeId);
ResourceObjectTuple resources = QueueManager.getResourcesForEvent(model, event);
if (resources == null) {
QueueManager.addToEventQueues(model, event);
sendTraceNote("Not enough resources available, task " + displayName + " is put in a queue.");
} else {
QueueManager.assignResourcesToEvent(model, event, resources);
TimeSpan timeSpan = new TimeSpan(0);
int index = getNewEventIndex();
nextEventMap.put(index, event);
timeSpanToNextEventMap.put(index, timeSpan);
}
TaskEnableEventPluggable.runPlugins(this, processInstance);
scheduleNextEvents();
} catch (ScyllaRuntimeException e) {
DebugLogger.error(e.getMessage());
DebugLogger.log("Simulation aborted.");
}
}
use of desmoj.core.simulator.TimeSpan in project scylla by bptlab.
the class SimulationUtils method scheduleNextResourceAvailableEvent.
/**
* Creates and schedules a DesmoJ event which represents a resource instance which returns from idle.
*
* @param model
* the simulation model
* @param resourceObject
* the resource instance returning from idle
* @param currentDateTime
* the current date time
* @param currentlyInTimetableItem
* true if the resource instance is currently active
*/
public static void scheduleNextResourceAvailableEvent(SimulationModel model, ResourceObject resourceObject, ZonedDateTime currentDateTime, boolean currentlyInTimetableItem) {
boolean showInTrace = model.traceIsOn();
TimeUnit timeUnit = DateTimeUtils.getReferenceTimeUnit();
long currentTime = DateTimeUtils.getTimeInstant(currentDateTime).getTimeRounded(timeUnit);
List<TimetableItem> timetable = resourceObject.getTimetable();
if (timetable == null) {
return;
}
int index = DateTimeUtils.getTimeTableIndexWithinOrNext(currentDateTime, timetable);
if (currentlyInTimetableItem) {
index++;
if (index == timetable.size()) {
index = 0;
}
}
TimetableItem nextTimetableItem = timetable.get(index);
DayOfWeek weekday = nextTimetableItem.getWeekdayFrom();
LocalTime time = nextTimetableItem.getBeginTime();
ZonedDateTime nextDateTime = DateTimeUtils.getNextZonedDateTime(currentDateTime, weekday, time);
long durationToNextResourceAvailableEvent = DateTimeUtils.getDuration(currentDateTime, nextDateTime);
if (model.getEndDateTime() != null) {
long endTimeRelativeToGlobalStart = DateTimeUtils.getDuration(model.getStartDateTime(), model.getEndDateTime());
if (currentTime + durationToNextResourceAvailableEvent >= endTimeRelativeToGlobalStart) {
return;
}
}
ResourceAvailabilityEvent event = new ResourceAvailabilityEvent(model, resourceObject, showInTrace);
event.schedule(new TimeSpan(durationToNextResourceAvailableEvent, timeUnit));
}
Aggregations