Search in sources :

Example 31 with TimeSpan

use of desmoj.core.simulator.TimeSpan 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)

Example 32 with TimeSpan

use of desmoj.core.simulator.TimeSpan in project scylla by bptlab.

the class BoundaryEventPluginUtils method scheduleBoundaryEvents.

private void scheduleBoundaryEvents(SimulationModel model, double startOfInterval, double endOfInterval) {
    Set<String> boundaryObjectsToRemove = new HashSet<>();
    for (String taskEnableEventName : boundaryObjects.keySet()) {
        // boolean isInterruptingEvent = false;
        BoundaryObject bo = boundaryObjects.get(taskEnableEventName);
        TreeMap<Double, List<BPMNIntermediateEvent>> boundaryEventsToSchedule = bo.getBoundaryEventsToSchedule();
        Iterator<Double> iterator = boundaryEventsToSchedule.keySet().iterator();
        Set<Double> elementsToRemove = new HashSet<>();
        ProcessInstance processInstance = bo.getProcessInstance();
        while (iterator.hasNext()) {
            Double timeToSchedule = iterator.next();
            if (timeToSchedule > endOfInterval) {
                // We will not have prepared events for scheduling which are beyond endOfInterval.
                break;
            }
            List<BPMNIntermediateEvent> events = boundaryEventsToSchedule.get(timeToSchedule);
            // Now take all events and schedule them.
            for (BPMNIntermediateEvent event : events) {
                double durationRelativeToEventStart = timeToSchedule - startOfInterval;
                if (durationRelativeToEventStart < 0)
                    continue;
                TimeUnit unit = TimeUnit.SECONDS;
                TimeSpan timeSpan = new TimeSpan(durationRelativeToEventStart, unit);
                // Schedule the event.
                try {
                    SimulationUtils.scheduleEvent(event, timeSpan);
                } catch (ScyllaRuntimeException exception) {
                    exception.printStackTrace();
                }
            /*ProcessModel processModel = processInstance.getProcessModel();
                    int nodeId = event.getNodeId();
                    boolean cancelActivity = processModel.getCancelActivities().get(nodeId);
                    if (cancelActivity) {
                        isInterruptingEvent = true;
                    }*/
            }
            // TreeMap<Double, List<String>> messagesOfBoundaryEventsToSchedule = bo.getMessagesOfBoundaryEventsToSchedule();
            // Took this out, see rest in createNonTimerBoundaryEvents.
            /*List<String> messages = messagesOfBoundaryEventsToSchedule.get(timeToSchedule);
                for (String message : messages) {
                    model.sendTraceNote(message);
                }*/
            // clean up
            elementsToRemove.add(timeToSchedule);
        // Not needed anymore, alreday done in creation.
        /*if (isInterruptingEvent) {
                    boundaryObjectsToRemove.add(taskEnableEventName);
                    // if (bo.getSource().equals(desmojEvent.getSource())) {
                    // normalBehavior = false;
                    // }
                    // processInstance.cancel();
                    break;
                }*/
        }
        for (Double timeToSchedule : elementsToRemove) {
            boundaryEventsToSchedule.remove(timeToSchedule);
            // messagesOfBoundaryEventsToSchedule.remove(timeToSchedule);
            if (boundaryEventsToSchedule.isEmpty()) {
                boundaryObjectsToRemove.add(taskEnableEventName);
            }
        }
    }
    // Delete all boudnaryObjects, which are compeltetly scheduled.
    for (String taskEnableEventName : boundaryObjectsToRemove) {
        boundaryObjects.remove(taskEnableEventName);
    }
}
Also used : ScyllaRuntimeException(de.hpi.bpt.scylla.exception.ScyllaRuntimeException) BPMNIntermediateEvent(de.hpi.bpt.scylla.simulation.event.BPMNIntermediateEvent) TimeSpan(desmoj.core.simulator.TimeSpan) TimeUnit(java.util.concurrent.TimeUnit) ArrayList(java.util.ArrayList) List(java.util.List) ProcessInstance(de.hpi.bpt.scylla.simulation.ProcessInstance) HashSet(java.util.HashSet)

Example 33 with TimeSpan

use of desmoj.core.simulator.TimeSpan in project scylla by bptlab.

the class BoundaryTBPlugin method eventRoutine.

@Override
public void eventRoutine(TaskBeginEvent desmojEvent, ProcessInstance processInstance) throws ScyllaRuntimeException {
    SimulationModel model = (SimulationModel) desmojEvent.getModel();
    ProcessModel processModel = processInstance.getProcessModel();
    int nodeId = desmojEvent.getNodeId();
    BoundaryEventPluginUtils pluginInstance = BoundaryEventPluginUtils.getInstance();
    // At the begin of each task check for corresponding boundary events. If there are some, create and schedule them.
    List<Integer> referenceToBoundaryEvents = processModel.getReferencesToBoundaryEvents().get(nodeId);
    if (referenceToBoundaryEvents != null) {
        double startTimeOfTask = model.presentTime().getTimeAsDouble(TimeUnit.SECONDS);
        // Create the corresponding boundary object for this task, which contains all necessary information.
        pluginInstance.initializeBoundaryObject(startTimeOfTask, desmojEvent, referenceToBoundaryEvents);
        // We usually do that in the event scheduling part, but in BoundaryEventSchedulingPlugin, it might not be called, if the TaskBeginEvent is put on a queue.
        // That is the reason why the eventroutine in the BoundaryEventSchedulingPlugin class is commented out and so on never used. We should not need it anymore and it could be deleted.
        // Create and schedule all boundary events this boundary object has for the current instance.
        pluginInstance.createAndScheduleBoundaryEvents(desmojEvent, new TimeSpan(0));
    }
}
Also used : TimeSpan(desmoj.core.simulator.TimeSpan) ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) SimulationModel(de.hpi.bpt.scylla.simulation.SimulationModel)

Example 34 with TimeSpan

use of desmoj.core.simulator.TimeSpan in project scylla by bptlab.

the class BPMNErrorBPMNEEPlugin method eventRoutine.

@Override
public void eventRoutine(BPMNEndEvent desmojEvent, ProcessInstance processInstance) throws ScyllaRuntimeException {
    SimulationModel model = (SimulationModel) desmojEvent.getModel();
    ProcessModel processModel = processInstance.getProcessModel();
    int nodeId = desmojEvent.getNodeId();
    Map<EventDefinitionType, Map<String, String>> definitions = processModel.getEventDefinitions().get(nodeId);
    ProcessSimulationComponents desmojObjects = desmojEvent.getDesmojObjects();
    boolean showInTrace = model.traceIsOn();
    try {
        for (EventDefinitionType definition : definitions.keySet()) {
            if (definition == EventDefinitionType.ERROR) {
                if (processModel.getParent() != null) {
                    Map<String, String> eventAttributes = processModel.getEventDefinitions().get(nodeId).get(definition);
                    String errorRef = eventAttributes.get("errorRef");
                    // Map<String, Map<String, String>> errors = model.getCommonProcessElements().getErrors();
                    // Map<String, String> error = errors.get("errorRef");
                    ProcessSimulationComponents parentDesmojObjects = desmojObjects.getParent();
                    ProcessModel parentModel = processModel.getParent();
                    int nodeIdInParent = processModel.getNodeIdInParent();
                    Integer nextNodeId = null;
                    // find boundary event of parentModel which has the same errorRef
                    List<Integer> referencesToBoundaryEvents = parentModel.getReferencesToBoundaryEvents().get(nodeIdInParent);
                    for (int nId : referencesToBoundaryEvents) {
                        Map<EventDefinitionType, Map<String, String>> boundaryEventDefinitions = parentModel.getEventDefinitions().get(nId);
                        Map<String, String> boundaryErrorEventDefinition = boundaryEventDefinitions.get(EventDefinitionType.ERROR);
                        if (boundaryErrorEventDefinition != null) {
                            if (errorRef.equals(boundaryErrorEventDefinition.get("errorRef"))) {
                                nextNodeId = nId;
                                break;
                            }
                        }
                    }
                    if (nextNodeId == null) {
                        DebugLogger.error("Could not find referenced error " + errorRef + ".");
                        SimulationUtils.abort(model, processInstance, nodeId, showInTrace);
                        return;
                    }
                    ProcessInstance parentProcessInstance = processInstance.getParent();
                    List<ScyllaEvent> events = SimulationUtils.createEventsForNextNode(desmojEvent, parentDesmojObjects, parentProcessInstance, nextNodeId);
                    TimeSpan timeSpan = new TimeSpan(0);
                    /**
                     * first event in the map is the node that comes after the subprocess when normal behavior
                     * applies, so remove it;
                     */
                    int indexOfTaskTerminateEvent = 0;
                    desmojEvent.getNextEventMap().remove(indexOfTaskTerminateEvent);
                    desmojEvent.getTimeSpanToNextEventMap().remove(indexOfTaskTerminateEvent);
                    for (ScyllaEvent event : events) {
                        int index = desmojEvent.getNewEventIndex();
                        desmojEvent.getNextEventMap().put(index, event);
                        desmojEvent.getTimeSpanToNextEventMap().put(index, timeSpan);
                    }
                    processInstance.cancel();
                }
            }
        }
    } catch (NodeNotFoundException | ScyllaValidationException e) {
        DebugLogger.error(e.getMessage());
        e.printStackTrace();
        SimulationUtils.abort(model, processInstance, nodeId, showInTrace);
    }
}
Also used : ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) EventDefinitionType(de.hpi.bpt.scylla.model.process.node.EventDefinitionType) ScyllaEvent(de.hpi.bpt.scylla.simulation.event.ScyllaEvent) 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) Map(java.util.Map) SimulationModel(de.hpi.bpt.scylla.simulation.SimulationModel)

Aggregations

TimeSpan (desmoj.core.simulator.TimeSpan)34 ProcessModel (de.hpi.bpt.scylla.model.process.ProcessModel)25 SimulationModel (de.hpi.bpt.scylla.simulation.SimulationModel)17 ScyllaEvent (de.hpi.bpt.scylla.simulation.event.ScyllaEvent)15 ScyllaRuntimeException (de.hpi.bpt.scylla.exception.ScyllaRuntimeException)12 NodeNotFoundException (de.hpi.bpt.scylla.model.process.graph.exception.NodeNotFoundException)11 ProcessInstance (de.hpi.bpt.scylla.simulation.ProcessInstance)11 TimeUnit (java.util.concurrent.TimeUnit)11 ProcessSimulationComponents (de.hpi.bpt.scylla.simulation.ProcessSimulationComponents)10 TimeInstant (desmoj.core.simulator.TimeInstant)9 ScyllaValidationException (de.hpi.bpt.scylla.exception.ScyllaValidationException)8 Map (java.util.Map)7 EventDefinitionType (de.hpi.bpt.scylla.model.process.node.EventDefinitionType)6 TaskTerminateEvent (de.hpi.bpt.scylla.simulation.event.TaskTerminateEvent)5 HashSet (java.util.HashSet)5 ArrayList (java.util.ArrayList)4 MultipleStartNodesException (de.hpi.bpt.scylla.model.process.graph.exception.MultipleStartNodesException)3 NoStartNodeException (de.hpi.bpt.scylla.model.process.graph.exception.NoStartNodeException)3 TaskType (de.hpi.bpt.scylla.model.process.node.TaskType)3 Duration (java.time.Duration)3