use of de.hpi.bpt.scylla.simulation.ProcessInstance in project scylla by bptlab.
the class BatchBPMNEEPlugin method eventRoutine.
@Override
public void eventRoutine(BPMNEndEvent event, ProcessInstance processInstance) throws ScyllaRuntimeException {
BatchPluginUtils pluginInstance = BatchPluginUtils.getInstance();
pluginInstance.logBPMNEventForNonResponsiblePI(event, processInstance);
// Schedule parental end events
ProcessInstance parentProcessInstance = processInstance.getParent();
if (parentProcessInstance != null) {
ProcessModel processModel = processInstance.getProcessModel();
int parentNodeId = processModel.getNodeIdInParent();
BatchCluster cluster = pluginInstance.getRunningCluster(parentProcessInstance, parentNodeId);
if (cluster != null) {
cluster.setProcessInstanceToFinished();
// Schedule them only if either all process instances has passed the last event of the batch activity or the execution type is parallel
if (cluster.areAllProcessInstancesFinished() || cluster.hasExecutionType(BatchClusterExecutionType.PARALLEL)) {
if (pluginInstance.isProcessInstanceCompleted(processInstance)) {
List<TaskTerminateEvent> parentalEndEvents = cluster.getParentalEndEvents();
for (TaskTerminateEvent pee : parentalEndEvents) {
ProcessInstance pi = pee.getProcessInstance();
pee.schedule(pi);
}
parentalEndEvents.clear();
pluginInstance.setClusterToTerminated(parentProcessInstance, parentNodeId);
}
// Prevent parental task terminate event from scheduling, if there is any (from subprocess plugin)
Map<Integer, ScyllaEvent> nextEventMap = event.getNextEventMap();
if (!nextEventMap.isEmpty()) {
Map<Integer, TimeSpan> timeSpanToNextEventMap = event.getTimeSpanToNextEventMap();
int indexOfParentalTaskTerminateEvent = 0;
nextEventMap.remove(indexOfParentalTaskTerminateEvent);
timeSpanToNextEventMap.remove(indexOfParentalTaskTerminateEvent);
}
} else if (cluster.hasExecutionType(BatchClusterExecutionType.SEQUENTIAL_CASEBASED)) {
// Schedule the next start event
pluginInstance.scheduleNextCaseInBatchProcess(cluster);
}
}
}
}
use of de.hpi.bpt.scylla.simulation.ProcessInstance in project scylla by bptlab.
the class BatchClusterStartEvent method eventRoutine.
@Override
public void eventRoutine(BatchCluster cluster) throws SuspendExecution {
BatchActivity activity = cluster.getBatchActivity();
int nodeId = activity.getNodeId();
List<TaskBeginEvent> parentalStartEvents = cluster.getParentalStartEvents();
// Schedule all task begin events of the process instance
for (TaskBeginEvent pse : parentalStartEvents) {
ProcessInstance pi = pse.getProcessInstance();
pse.schedule(pi);
}
// schedule subprocess start events for all process instances in parent
// processInstances and parentalStartEvents are ordered the same way
// Set the responsible process instance in the batch cluster, first one by default
cluster.setResponsibleProcessInstance(parentalStartEvents.get(0).getProcessInstance());
// Go through all process instances. If it's the first one, schedule it. If not, save it to be scheduled later on
for (int j = 0; j < parentalStartEvents.size(); j++) {
TaskBeginEvent startEvent = parentalStartEvents.get(j);
ProcessInstance responsibleProcessInstance = startEvent.getProcessInstance();
int processInstanceId = responsibleProcessInstance.getId();
boolean showInTrace = responsibleProcessInstance.traceIsOn();
SimulationModel model = (SimulationModel) responsibleProcessInstance.getModel();
String source = startEvent.getSource();
TimeInstant currentSimulationTime = cluster.presentTime();
ProcessSimulationComponents pSimComponentsOfSubprocess = cluster.getProcessSimulationComponents().getChildren().get(nodeId);
ProcessModel subprocess = pSimComponentsOfSubprocess.getProcessModel();
try {
Integer startNodeId = subprocess.getStartNode();
ProcessInstance subprocessInstance = new ProcessInstance(model, subprocess, processInstanceId, showInTrace);
subprocessInstance.setParent(responsibleProcessInstance);
ScyllaEvent subprocessEvent = new BPMNStartEvent(model, source, currentSimulationTime, pSimComponentsOfSubprocess, subprocessInstance, startNodeId);
System.out.println("Created BPMNStartEvent for PI " + subprocessInstance.getId() + " / " + responsibleProcessInstance.getId() + " in Batch Cluster");
if (j == 0) {
// If it is the first process instance, schedule it...
subprocessEvent.schedule(subprocessInstance);
cluster.setStartNodeId(startNodeId);
} else {
// ...if not, save them for later
cluster.addPIEvent(startNodeId, subprocessEvent, subprocessInstance);
}
} catch (NodeNotFoundException | MultipleStartNodesException | NoStartNodeException e) {
DebugLogger.log("Start node of process model " + subprocess.getId() + " not found.");
System.err.println(e.getMessage());
e.printStackTrace();
SimulationUtils.abort(model, responsibleProcessInstance, nodeId, traceIsOn());
return;
}
}
// move batch cluster from list of not started ones to running ones
BatchPluginUtils pluginInstance = BatchPluginUtils.getInstance();
pluginInstance.setClusterToRunning(cluster);
// next node and timespan to next event determined by responsible process instance
// tasks resources only assigned to responsible subprocess instance
// only responsible subprocess instance is simulated
// other subprocess instances of batch are covered in process logs
}
use of de.hpi.bpt.scylla.simulation.ProcessInstance in project scylla by bptlab.
the class BatchLogger method writeToLog.
public void writeToLog(SimulationModel model, String outputPathWithoutExtension) throws IOException {
StringBuffer sb = new StringBuffer();
BatchPluginUtils pluginInstance = BatchPluginUtils.getInstance();
Map<String, Map<Integer, List<BatchCluster>>> clusters = pluginInstance.getBatchClusters();
TimeUnit referenceTimeUnit = DateTimeUtils.getReferenceTimeUnit();
sb.append("BATCH REPORT" + System.lineSeparator());
sb.append("Reference unit: " + referenceTimeUnit + System.lineSeparator());
sb.append("Please note: Duration and cost of batch activity execution can be found in output file of statslogger plug-in." + System.lineSeparator());
sb.append(System.lineSeparator());
for (String processId : clusters.keySet()) {
sb.append("=== PROCESS " + processId + " ===" + System.lineSeparator());
Map<Integer, List<BatchCluster>> clustersOfProcess = clusters.get(processId);
for (Integer nodeId : clustersOfProcess.keySet()) {
sb.append("== Node " + nodeId + System.lineSeparator());
double waitingTimeMaximumAllActivities = -1;
List<Double> waitingTimeAveragesAllActivities = new ArrayList<Double>();
List<BatchCluster> bcs = clustersOfProcess.get(nodeId);
for (BatchCluster bc : bcs) {
sb.append(System.lineSeparator());
sb.append("-- " + bc.getName() + System.lineSeparator());
double startTimeInRefUnit = bc.getStartTime().getTimeAsDouble(referenceTimeUnit);
double maximumWaitingTime = startTimeInRefUnit - bc.getCreationTime().getTimeAsDouble(referenceTimeUnit);
if (maximumWaitingTime > waitingTimeMaximumAllActivities) {
waitingTimeMaximumAllActivities = maximumWaitingTime;
}
sb.append("Maximum waiting time: " + maximumWaitingTime + System.lineSeparator());
List<TimeInstant> entranceTimes = bc.getProcessInstanceEntranceTimes();
List<Double> waitingTimes = new ArrayList<Double>();
for (TimeInstant et : entranceTimes) {
waitingTimes.add(startTimeInRefUnit - et.getTimeAsDouble(referenceTimeUnit));
}
double avgWaitingTime = DateTimeUtils.mean(waitingTimes);
waitingTimeAveragesAllActivities.add(avgWaitingTime);
sb.append("Average waiting time: " + avgWaitingTime + System.lineSeparator());
List<ProcessInstance> processInstances = bc.getProcessInstances();
List<Integer> processInstanceIds = new ArrayList<Integer>();
for (ProcessInstance pi : processInstances) {
processInstanceIds.add(pi.getId());
}
sb.append("Process instances: " + processInstanceIds + " (" + processInstanceIds.size() + " process instance(s))" + System.lineSeparator());
}
sb.append(System.lineSeparator());
sb.append("Maximum waiting time of all activities: " + waitingTimeMaximumAllActivities + System.lineSeparator());
sb.append("Average waiting time of all activities: " + DateTimeUtils.mean(waitingTimeAveragesAllActivities) + System.lineSeparator());
}
sb.append(System.lineSeparator());
}
if (outputPathWithoutExtension == null) {
System.out.println(sb.toString());
} else {
String resourceUtilizationFileName = outputPathWithoutExtension + model.getGlobalConfiguration().getFileNameWithoutExtension() + "_batchactivitystats.txt";
PrintWriter writer = new PrintWriter(resourceUtilizationFileName, "UTF-8");
writer.println(sb.toString());
writer.close();
System.out.println("Wrote batch activity statistics to " + resourceUtilizationFileName);
}
}
use of de.hpi.bpt.scylla.simulation.ProcessInstance in project scylla by bptlab.
the class BatchPluginUtils method getRunningCluster.
BatchCluster getRunningCluster(ProcessInstance processInstance, int nodeId) {
ProcessModel processModel = processInstance.getProcessModel();
String processId = processModel.getId();
if (batchClusters.containsKey(processId)) {
Map<Integer, List<BatchCluster>> batchClustersOfProcess = batchClusters.get(processId);
if (batchClustersOfProcess.containsKey(nodeId)) {
List<BatchCluster> clusters = batchClustersOfProcess.get(nodeId);
for (BatchCluster bc : clusters) {
List<ProcessInstance> clusterProcessInstances = bc.getProcessInstances();
if (bc.getState() == BatchClusterState.RUNNING && clusterProcessInstances.contains(processInstance)) {
return bc;
}
}
}
}
return null;
}
use of de.hpi.bpt.scylla.simulation.ProcessInstance in project scylla by bptlab.
the class BatchPluginUtils method scheduleNextEventInBatchProcess.
// if the execution type is sequential-taskbased, this is responsible for scheduling the same event of the next process instance, if it exists
void scheduleNextEventInBatchProcess(ScyllaEvent event, ProcessInstance processInstance) {
ProcessInstance parentProcessInstance = processInstance.getParent();
if (parentProcessInstance != null) {
ProcessModel processModel = processInstance.getProcessModel();
int parentNodeId = processModel.getNodeIdInParent();
BatchPluginUtils pluginInstance = BatchPluginUtils.getInstance();
BatchCluster cluster = pluginInstance.getRunningCluster(parentProcessInstance, parentNodeId);
if (cluster != null && cluster.hasExecutionType(BatchClusterExecutionType.SEQUENTIAL_TASKBASED)) {
// Get the other events or tasks from this batch to be scheduled after the current one...
Integer nodeId = event.getNodeId();
Pair<ScyllaEvent, ProcessInstance> eventToSchedule = cluster.getNotPIEvents(nodeId);
if (eventToSchedule != null) {
eventToSchedule.getValue0().schedule(eventToSchedule.getValue1());
// System.out.println("Scheduled " + eventToSchedule.getValue0().getDisplayName() + " for process instance " + eventToSchedule.getValue1());
}
if (parentProcessInstance != cluster.getResponsibleProcessInstance()) {
// ..and save the next events before them getting clered
ScyllaEvent nextEvent = event.getNextEventMap().get(0);
Integer nodeIdOfNextElement = nextEvent.getNodeId();
cluster.addPIEvent(nodeIdOfNextElement, nextEvent, processInstance);
// System.out.println("Added " + nextEvent.getDisplayName() + " to cluster queue for process instance " + processInstance);
}
}
}
}
Aggregations