Search in sources :

Example 11 with ProcessSimulationComponents

use of de.hpi.bpt.scylla.simulation.ProcessSimulationComponents in project scylla by bptlab.

the class EventArrivalRateSchedulingPlugin method scheduleEvent.

/**
 * Gets a sample of the arrival rate distribution for this event, if existing,
 * and schedules the event displaced by this value.
 */
@Override
public boolean scheduleEvent(ScyllaEvent event, TimeSpan timeSpan) throws ScyllaRuntimeException {
    ProcessSimulationComponents pSimComponents = event.getDesmojObjects();
    Map<Integer, Object> arrivalRates = pSimComponents.getExtensionDistributions().get(getName());
    @SuppressWarnings("unchecked") SimpleEntry<NumericalDist<?>, TimeUnit> arrivalRate = (SimpleEntry<NumericalDist<?>, TimeUnit>) arrivalRates.get(event.getNodeId());
    if (arrivalRate != null) {
        NumericalDist<?> distribution = arrivalRate.getKey();
        TimeUnit timeUnit = arrivalRate.getValue();
        ProcessInstance processInstance = event.getProcessInstance();
        TimeSpan offset = new TimeSpan(distribution.sample().doubleValue(), timeUnit);
        TimeSpan newTime = new TimeSpan(timeSpan.getTimeAsDouble() + offset.getTimeAsDouble());
        event.schedule(processInstance, newTime);
        return false;
    }
    return true;
}
Also used : TimeSpan(desmoj.core.simulator.TimeSpan) NumericalDist(desmoj.core.dist.NumericalDist) ProcessSimulationComponents(de.hpi.bpt.scylla.simulation.ProcessSimulationComponents) SimpleEntry(java.util.AbstractMap.SimpleEntry) TimeUnit(java.util.concurrent.TimeUnit) ProcessInstance(de.hpi.bpt.scylla.simulation.ProcessInstance)

Example 12 with ProcessSimulationComponents

use of de.hpi.bpt.scylla.simulation.ProcessSimulationComponents in project scylla by bptlab.

the class SubprocessBPMNEEPlugin method eventRoutine.

@Override
public void eventRoutine(BPMNEndEvent desmojEvent, ProcessInstance processInstance) throws ScyllaRuntimeException {
    ProcessModel processModel = processInstance.getProcessModel();
    if (processModel.getParent() != null && processInstanceIsCompleted(processInstance)) {
        // works
        try {
            ProcessSimulationComponents desmojObjects = desmojEvent.getDesmojObjects();
            ProcessSimulationComponents parentDesmojObjects = desmojObjects.getParent();
            ProcessModel parentModel = processModel.getParent();
            int nodeIdInParent = processModel.getNodeIdInParent();
            ProcessInstance parentProcessInstance = processInstance.getParent();
            // behavior when sub-process sends events:
            // none -> back to normal flow
            // message -> "send it"
            // error -> to parent
            // escalation -> to parent
            // cancel -> nonono!
            // compensation -> ... not now
            // signal -> ... not now
            // terminate -> terminate sub-process (kill all events of sub-process instance (MI sub-process
            // not affected))
            // ...
            // timer -> special treatment
            Set<Integer> idsOfNextNodes = parentModel.getIdsOfNextNodes(nodeIdInParent);
            // normal flow: must not have more than one successor
            if (idsOfNextNodes.size() != 1) {
                int nodeId = desmojEvent.getNodeId();
                throw new ScyllaValidationException("Subprocess " + nodeId + " does not have 1 successor, but " + idsOfNextNodes.size() + ".");
            }
            Integer nextNodeId = idsOfNextNodes.iterator().next();
            // TODO let the parent create the next node, so remove the lines below
            List<ScyllaEvent> events = SimulationUtils.createEventsForNextNode(desmojEvent, parentDesmojObjects, parentProcessInstance, nextNodeId);
            // next event occurs immediately after start event
            TimeSpan timeSpan = new TimeSpan(0);
            String parentProcessInstanceName = parentProcessInstance.getName();
            SubprocessPluginUtils pluginInstance = SubprocessPluginUtils.getInstance();
            TaskTerminateEvent eventOfParent = pluginInstance.getEventsOnHold().get(parentProcessInstanceName).get(nodeIdInParent);
            if (eventOfParent != null) {
                events.add(eventOfParent);
                pluginInstance.getEventsOnHold().get(parentProcessInstanceName).remove(nodeIdInParent);
                pluginInstance.getNameOfEventsThatWereOnHold().add(eventOfParent.getName());
            }
            for (ScyllaEvent event : events) {
                int index = desmojEvent.getNewEventIndex();
                desmojEvent.getNextEventMap().put(index, event);
                desmojEvent.getTimeSpanToNextEventMap().put(index, timeSpan);
            }
        } catch (NodeNotFoundException | ScyllaValidationException | ScyllaRuntimeException e) {
            SimulationModel model = (SimulationModel) desmojEvent.getModel();
            int nodeId = desmojEvent.getNodeId();
            boolean showInTrace = model.traceIsOn();
            DebugLogger.error(e.getMessage());
            e.printStackTrace();
            SimulationUtils.abort(model, processInstance, nodeId, showInTrace);
        }
    }
}
Also used : ScyllaRuntimeException(de.hpi.bpt.scylla.exception.ScyllaRuntimeException) ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) ScyllaEvent(de.hpi.bpt.scylla.simulation.event.ScyllaEvent) TaskTerminateEvent(de.hpi.bpt.scylla.simulation.event.TaskTerminateEvent) TimeSpan(desmoj.core.simulator.TimeSpan) ScyllaValidationException(de.hpi.bpt.scylla.exception.ScyllaValidationException) NodeNotFoundException(de.hpi.bpt.scylla.model.process.graph.exception.NodeNotFoundException) ProcessSimulationComponents(de.hpi.bpt.scylla.simulation.ProcessSimulationComponents) ProcessInstance(de.hpi.bpt.scylla.simulation.ProcessInstance) SimulationModel(de.hpi.bpt.scylla.simulation.SimulationModel)

Example 13 with ProcessSimulationComponents

use of de.hpi.bpt.scylla.simulation.ProcessSimulationComponents in project scylla by bptlab.

the class SubprocessTBPlugin method eventRoutine.

@Override
public void eventRoutine(TaskBeginEvent desmojEvent, ProcessInstance processInstance) throws ScyllaRuntimeException {
    ProcessModel processModel = processInstance.getProcessModel();
    int nodeId = desmojEvent.getNodeId();
    ProcessModel subProcess = processModel.getSubProcesses().get(nodeId);
    if (subProcess != null) {
        int indexOfTaskTerminateEvent = 0;
        desmojEvent.getTimeSpanToNextEventMap().remove(indexOfTaskTerminateEvent);
        TaskTerminateEvent event = (TaskTerminateEvent) desmojEvent.getNextEventMap().get(indexOfTaskTerminateEvent);
        String name = processInstance.getName();
        SubprocessPluginUtils pluginInstance = SubprocessPluginUtils.getInstance();
        Map<Integer, TaskTerminateEvent> eventsOnHoldMap = pluginInstance.getEventsOnHold().get(name);
        if (eventsOnHoldMap == null) {
            pluginInstance.getEventsOnHold().put(name, new HashMap<Integer, TaskTerminateEvent>());
        }
        pluginInstance.getEventsOnHold().get(name).put(nodeId, event);
        desmojEvent.getNextEventMap().remove(indexOfTaskTerminateEvent);
        String source = desmojEvent.getSource();
        ProcessSimulationComponents desmojObjects = desmojEvent.getDesmojObjects();
        SimulationModel model = (SimulationModel) desmojEvent.getModel();
        TimeInstant currentSimulationTime = model.presentTime();
        boolean showInTrace = model.traceIsOn();
        int processInstanceId = processInstance.getId();
        try {
            ProcessSimulationComponents desmojObjectsOfSubProcess = desmojObjects.getChildren().get(nodeId);
            Integer startNodeId = subProcess.getStartNode();
            ProcessInstance subProcessInstance = new ProcessInstance(model, subProcess, processInstanceId, showInTrace);
            subProcessInstance.setParent(processInstance);
            ScyllaEvent subProcessEvent = new BPMNStartEvent(model, source, currentSimulationTime, desmojObjectsOfSubProcess, subProcessInstance, startNodeId);
            TimeSpan timeSpan = new TimeSpan(0);
            int index = desmojEvent.getNewEventIndex();
            desmojEvent.getNextEventMap().put(index, subProcessEvent);
            desmojEvent.getTimeSpanToNextEventMap().put(index, timeSpan);
        } catch (NodeNotFoundException | MultipleStartNodesException | NoStartNodeException e) {
            DebugLogger.error(e.getMessage());
            DebugLogger.log("Start node of process model " + subProcess.getId() + " not found.");
            throw new ScyllaRuntimeException("Start node of process model " + subProcess.getId() + " not found.");
        }
    }
}
Also used : ScyllaRuntimeException(de.hpi.bpt.scylla.exception.ScyllaRuntimeException) ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) ScyllaEvent(de.hpi.bpt.scylla.simulation.event.ScyllaEvent) TaskTerminateEvent(de.hpi.bpt.scylla.simulation.event.TaskTerminateEvent) MultipleStartNodesException(de.hpi.bpt.scylla.model.process.graph.exception.MultipleStartNodesException) TimeSpan(desmoj.core.simulator.TimeSpan) 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 14 with ProcessSimulationComponents

use of de.hpi.bpt.scylla.simulation.ProcessSimulationComponents 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);
    }
}
Also used : ScyllaRuntimeException(de.hpi.bpt.scylla.exception.ScyllaRuntimeException) ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) MultipleStartNodesException(de.hpi.bpt.scylla.model.process.graph.exception.MultipleStartNodesException) TimeSpan(desmoj.core.simulator.TimeSpan) NodeNotFoundException(de.hpi.bpt.scylla.model.process.graph.exception.NodeNotFoundException) ProcessSimulationComponents(de.hpi.bpt.scylla.simulation.ProcessSimulationComponents) TimeUnit(java.util.concurrent.TimeUnit) ProcessInstance(de.hpi.bpt.scylla.simulation.ProcessInstance) SimulationModel(de.hpi.bpt.scylla.simulation.SimulationModel) TimeInstant(desmoj.core.simulator.TimeInstant) NoStartNodeException(de.hpi.bpt.scylla.model.process.graph.exception.NoStartNodeException)

Example 15 with ProcessSimulationComponents

use of de.hpi.bpt.scylla.simulation.ProcessSimulationComponents in project scylla by bptlab.

the class BatchPluginUtils method assignToBatchCluster.

@SuppressWarnings("unchecked")
void assignToBatchCluster(ProcessInstance processInstance, int nodeId, TaskBeginEvent parentalBeginEvent) {
    ProcessModel processModel = processInstance.getProcessModel();
    ProcessSimulationComponents pSimComponents = parentalBeginEvent.getDesmojObjects();
    /*Map<Integer, BatchActivity> batchActivities_old = (Map<Integer, BatchActivity>) pSimComponents.getSimulationConfiguration()
                .getExtensionValue(PLUGIN_NAME, "batchActivities");*/
    Map<Integer, BatchActivity> batchActivities = processModel.getBatchActivities();
    BatchActivity activity = batchActivities.get(nodeId);
    BatchCluster cluster = null;
    // (1) select the right batch cluster
    // (1a) check if there is already a batch with the data view
    String processId = processModel.getId();
    Map<Integer, List<BatchCluster>> batchClustersOfProcess = batchClusters.get(processId);
    if (batchClustersOfProcess != null) {
        List<BatchCluster> clusters = batchClustersOfProcess.get(nodeId);
        if (clusters != null) {
            for (BatchCluster bc : clusters) {
                if (batchClusterHasNotStarted(bc.getState()) && isProcessInstanceMatchingToDataView(parentalBeginEvent, processInstance, bc)) {
                    cluster = bc;
                    // clusters.remove(bc);
                    break;
                }
            }
        }
    }
    // (1b) if not, create a new one
    if (cluster == null) {
        Model model = processInstance.getModel();
        boolean showInTrace = processInstance.traceIsOn();
        Map<String, Object> dataView = this.getDataViewOfInstance(parentalBeginEvent, processInstance, activity);
        TimeInstant currentSimulationTime = processInstance.presentTime();
        cluster = new BatchCluster(model, currentSimulationTime, pSimComponents, activity, nodeId, dataView, showInTrace);
        // schedule BatchClusterStart at current time plus maximum timeout
        BatchClusterStartEvent clusterStartEvent = new BatchClusterStartEvent(model, cluster.getName(), showInTrace);
        Duration timeout = activity.getActivationRule().getTimeOut(parentalBeginEvent, processInstance);
        cluster.setCurrentTimeOut(timeout);
        long timeoutInSeconds = timeout.get(ChronoUnit.SECONDS);
        TimeSpan timeSpan = new TimeSpan(timeoutInSeconds, TimeUnit.SECONDS);
        clusterStartEvent.schedule(cluster, timeSpan);
        if (batchClustersOfProcess == null) {
            batchClustersOfProcess = new HashMap<Integer, List<BatchCluster>>();
            batchClusters.put(processId, batchClustersOfProcess);
            List<BatchCluster> clusters = batchClustersOfProcess.get(nodeId);
            if (clusters == null) {
                clusters = new ArrayList<BatchCluster>();
                batchClustersOfProcess.put(nodeId, clusters);
            }
        }
        batchClustersOfProcess.get(nodeId).add(cluster);
    }
    // (2) add process instance to cluster
    cluster.addProcessInstance(processInstance, parentalBeginEvent);
    // TODO check whether timeout should be updated
    if (cluster.getState() == BatchClusterState.INIT && cluster.getProcessInstances().size() > 1) {
        // if the dueDate of the current instance is earlier as of the instances added before, the cluster begin event is rescheduled
        Duration timeoutForCurrentInstance = activity.getActivationRule().getTimeOut(parentalBeginEvent, processInstance);
        // testing
        TimeUnit epsilon = TimeUnit.SECONDS;
        Duration durationBtwClusterStartAndInstanceTaskBegin = Duration.ofSeconds((long) (parentalBeginEvent.getSimulationTimeOfSource().getTimeAsDouble(epsilon) - cluster.getCreationTime().getTimeAsDouble(epsilon)));
        // System.out.println("InstanceEnable: "+parentalBeginEvent.getSimulationTimeOfSource().getTimeAsDouble(epsilon)+" ClusterCreation: "+cluster.getCreationTime().getTimeAsDouble(epsilon)+" Duration "+durationBtwClusterStartAndInstanceTaskBegin);
        if (timeoutForCurrentInstance.plus(durationBtwClusterStartAndInstanceTaskBegin).compareTo(cluster.getCurrentTimeOut()) < 0) {
            // set new timeout for the cluster for comparison
            cluster.setCurrentTimeOut(timeoutForCurrentInstance);
            // reschedule the cluster beginEvent
            long timeoutInSeconds = timeoutForCurrentInstance.get(ChronoUnit.SECONDS);
            TimeSpan timeSpan = new TimeSpan(timeoutInSeconds, TimeUnit.SECONDS);
            BatchClusterStartEvent clusterStartEvent = (BatchClusterStartEvent) cluster.getScheduledEvents().get(0);
            cluster.cancel();
            clusterStartEvent.schedule(cluster, timeSpan);
        }
    }
    if (cluster.getState() == BatchClusterState.MAXLOADED) {
        // (2a) if bc is maxloaded, reschedule BatchClusterStart
        // there is only one event already scheduled for the cluster which is the BatchClusterStart
        BatchClusterStartEvent clusterStartEvent = (BatchClusterStartEvent) cluster.getScheduledEvents().get(0);
        cluster.cancel();
        // schedule for immediate execution
        clusterStartEvent.schedule(cluster);
    }
}
Also used : ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) Duration(java.time.Duration) TimeSpan(desmoj.core.simulator.TimeSpan) ProcessSimulationComponents(de.hpi.bpt.scylla.simulation.ProcessSimulationComponents) ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) SimulationModel(de.hpi.bpt.scylla.simulation.SimulationModel) Model(desmoj.core.simulator.Model) TimeUnit(java.util.concurrent.TimeUnit) ArrayList(java.util.ArrayList) List(java.util.List) ResourceObject(de.hpi.bpt.scylla.simulation.ResourceObject) TimeInstant(desmoj.core.simulator.TimeInstant)

Aggregations

ProcessSimulationComponents (de.hpi.bpt.scylla.simulation.ProcessSimulationComponents)16 ProcessModel (de.hpi.bpt.scylla.model.process.ProcessModel)13 ProcessInstance (de.hpi.bpt.scylla.simulation.ProcessInstance)11 SimulationModel (de.hpi.bpt.scylla.simulation.SimulationModel)11 TimeSpan (desmoj.core.simulator.TimeSpan)11 NodeNotFoundException (de.hpi.bpt.scylla.model.process.graph.exception.NodeNotFoundException)8 ScyllaEvent (de.hpi.bpt.scylla.simulation.event.ScyllaEvent)7 TimeUnit (java.util.concurrent.TimeUnit)7 TimeInstant (desmoj.core.simulator.TimeInstant)6 ScyllaRuntimeException (de.hpi.bpt.scylla.exception.ScyllaRuntimeException)5 ScyllaValidationException (de.hpi.bpt.scylla.exception.ScyllaValidationException)5 Map (java.util.Map)5 MultipleStartNodesException (de.hpi.bpt.scylla.model.process.graph.exception.MultipleStartNodesException)4 NoStartNodeException (de.hpi.bpt.scylla.model.process.graph.exception.NoStartNodeException)4 EventDefinitionType (de.hpi.bpt.scylla.model.process.node.EventDefinitionType)4 ArrayList (java.util.ArrayList)4 BPMNStartEvent (de.hpi.bpt.scylla.simulation.event.BPMNStartEvent)3 TaskTerminateEvent (de.hpi.bpt.scylla.simulation.event.TaskTerminateEvent)3 DiscreteDistEmpirical (desmoj.core.dist.DiscreteDistEmpirical)3 Duration (java.time.Duration)3