Search in sources :

Example 1 with ProcessInstance

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);
            }
        }
    }
}
Also used : TimeSpan(desmoj.core.simulator.TimeSpan) ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) ProcessInstance(de.hpi.bpt.scylla.simulation.ProcessInstance) ScyllaEvent(de.hpi.bpt.scylla.simulation.event.ScyllaEvent) TaskTerminateEvent(de.hpi.bpt.scylla.simulation.event.TaskTerminateEvent)

Example 2 with ProcessInstance

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
}
Also used : ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) TaskBeginEvent(de.hpi.bpt.scylla.simulation.event.TaskBeginEvent) ScyllaEvent(de.hpi.bpt.scylla.simulation.event.ScyllaEvent) MultipleStartNodesException(de.hpi.bpt.scylla.model.process.graph.exception.MultipleStartNodesException) NodeNotFoundException(de.hpi.bpt.scylla.model.process.graph.exception.NodeNotFoundException) ProcessSimulationComponents(de.hpi.bpt.scylla.simulation.ProcessSimulationComponents) ProcessInstance(de.hpi.bpt.scylla.simulation.ProcessInstance) BPMNStartEvent(de.hpi.bpt.scylla.simulation.event.BPMNStartEvent) SimulationModel(de.hpi.bpt.scylla.simulation.SimulationModel) TimeInstant(desmoj.core.simulator.TimeInstant) NoStartNodeException(de.hpi.bpt.scylla.model.process.graph.exception.NoStartNodeException)

Example 3 with ProcessInstance

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);
    }
}
Also used : ArrayList(java.util.ArrayList) TimeUnit(java.util.concurrent.TimeUnit) ArrayList(java.util.ArrayList) List(java.util.List) ProcessInstance(de.hpi.bpt.scylla.simulation.ProcessInstance) Map(java.util.Map) TimeInstant(desmoj.core.simulator.TimeInstant) PrintWriter(java.io.PrintWriter)

Example 4 with ProcessInstance

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;
}
Also used : ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) ArrayList(java.util.ArrayList) List(java.util.List) ProcessInstance(de.hpi.bpt.scylla.simulation.ProcessInstance)

Example 5 with ProcessInstance

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);
            }
        }
    }
}
Also used : ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) ProcessInstance(de.hpi.bpt.scylla.simulation.ProcessInstance)

Aggregations

ProcessInstance (de.hpi.bpt.scylla.simulation.ProcessInstance)24 ProcessModel (de.hpi.bpt.scylla.model.process.ProcessModel)18 SimulationModel (de.hpi.bpt.scylla.simulation.SimulationModel)12 TimeSpan (desmoj.core.simulator.TimeSpan)12 ProcessSimulationComponents (de.hpi.bpt.scylla.simulation.ProcessSimulationComponents)11 ScyllaEvent (de.hpi.bpt.scylla.simulation.event.ScyllaEvent)8 TimeInstant (desmoj.core.simulator.TimeInstant)8 ScyllaRuntimeException (de.hpi.bpt.scylla.exception.ScyllaRuntimeException)7 TimeUnit (java.util.concurrent.TimeUnit)7 NodeNotFoundException (de.hpi.bpt.scylla.model.process.graph.exception.NodeNotFoundException)6 TaskTerminateEvent (de.hpi.bpt.scylla.simulation.event.TaskTerminateEvent)6 ArrayList (java.util.ArrayList)5 HashSet (java.util.HashSet)5 List (java.util.List)5 Map (java.util.Map)4 ScyllaValidationException (de.hpi.bpt.scylla.exception.ScyllaValidationException)3 ProcessNodeInfo (de.hpi.bpt.scylla.logger.ProcessNodeInfo)3 MultipleStartNodesException (de.hpi.bpt.scylla.model.process.graph.exception.MultipleStartNodesException)3 NoStartNodeException (de.hpi.bpt.scylla.model.process.graph.exception.NoStartNodeException)3 EventDefinitionType (de.hpi.bpt.scylla.model.process.node.EventDefinitionType)3