Search in sources :

Example 16 with ScyllaEvent

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

the class EventbasedGatewayEventPlugin method eventRoutine.

/**
 * Handles a gateway event, if it is an event based gateway
 * Changes scheduling behavior by already scheduling the next events of the given gateway event (if event based)
 */
@Override
public void eventRoutine(GatewayEvent desmojEvent, ProcessInstance processInstance) throws ScyllaRuntimeException {
    SimulationModel model = (SimulationModel) desmojEvent.getModel();
    ProcessModel processModel = processInstance.getProcessModel();
    int nodeId = desmojEvent.getNodeId();
    GatewayType type = processModel.getGateways().get(nodeId);
    try {
        Set<Integer> idsOfNextNodes = processModel.getIdsOfNextNodes(nodeId);
        if (type == GatewayType.EVENT_BASED && idsOfNextNodes.size() > 1) {
            // Schedule all following events
            List<ScyllaEvent> nextEvents = new ArrayList<ScyllaEvent>(desmojEvent.getNextEventMap().values());
            desmojEvent.scheduleNextEvents();
            // and look which is scheduled first.
            ScyllaEvent first = nextEvents.get(0);
            for (ScyllaEvent e : nextEvents) {
                if (TimeInstant.isBefore(e.scheduledNext(), first.scheduledNext())) {
                    first = e;
                }
            }
            // Cancel all other events except the one that is scheduled first.
            nextEvents.remove(first);
            for (ScyllaEvent e : nextEvents) {
                e.cancel();
            }
        }
    } catch (NodeNotFoundException | ScyllaValidationException | SuspendExecution e) {
        e.printStackTrace();
        // Critical error (following nodes not found or validation error), abort the instance.
        SimulationUtils.abort(model, processInstance, nodeId, desmojEvent.traceIsOn());
    }
}
Also used : ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) SuspendExecution(co.paralleluniverse.fibers.SuspendExecution) ArrayList(java.util.ArrayList) GatewayType(de.hpi.bpt.scylla.model.process.node.GatewayType) ScyllaEvent(de.hpi.bpt.scylla.simulation.event.ScyllaEvent) ScyllaValidationException(de.hpi.bpt.scylla.exception.ScyllaValidationException) NodeNotFoundException(de.hpi.bpt.scylla.model.process.graph.exception.NodeNotFoundException) SimulationModel(de.hpi.bpt.scylla.simulation.SimulationModel)

Example 17 with ScyllaEvent

use of de.hpi.bpt.scylla.simulation.event.ScyllaEvent 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 18 with ScyllaEvent

use of de.hpi.bpt.scylla.simulation.event.ScyllaEvent 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 19 with ScyllaEvent

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

the class QueueManager method getEventFromQueueReadyForSchedule.

/**
 * Returns eventwhich is ready to be scheduled for immediate execution from event queues.
 *
 * @param model
 *            the simulation model
 * @param resourceQueuesUpdated
 *            resource queues which have been updated recently -> only the events which require resources from these
 *            queues are considered
 * @return the DesmoJ event which is ready to be scheduled for immediate execution
 */
public static ScyllaEvent getEventFromQueueReadyForSchedule(SimulationModel model, Set<String> resourceQueuesUpdated) {
    List<ScyllaEvent> eventCandidates = new ArrayList<ScyllaEvent>();
    int accumulatedIndex = Integer.MAX_VALUE;
    for (String resourceId : resourceQueuesUpdated) {
        ScyllaEventQueue eventQueue = model.getEventQueues().get(resourceId);
        for (int i = 0; i < eventQueue.size(); i++) {
            ScyllaEvent eventFromQueue = eventQueue.peek(i);
            if (eventCandidates.contains(eventFromQueue)) {
                continue;
            }
            int index = 0;
            boolean eventIsEligible = hasResourcesForEvent(model, eventFromQueue);
            if (eventIsEligible) {
                ProcessSimulationComponents desmojObjects = eventFromQueue.getDesmojObjects();
                int nodeId = eventFromQueue.getNodeId();
                Set<ResourceReference> resourceReferences = desmojObjects.getSimulationConfiguration().getResourceReferenceSet(nodeId);
                for (ResourceReference ref : resourceReferences) {
                    // add position in queue and add to index
                    String resId = ref.getResourceId();
                    ScyllaEventQueue eventQ = model.getEventQueues().get(resId);
                    index += eventQ.getIndex(eventFromQueue);
                }
                if (accumulatedIndex < index) {
                    break;
                } else if (accumulatedIndex == index) {
                    eventCandidates.add(eventFromQueue);
                } else if (accumulatedIndex > index) {
                    accumulatedIndex = index;
                    eventCandidates.clear();
                    eventCandidates.add(eventFromQueue);
                }
            }
        }
    }
    if (eventCandidates.isEmpty()) {
        return null;
    } else {
        Collections.sort(eventCandidates, new Comparator<ScyllaEvent>() {

            @Override
            public int compare(ScyllaEvent e1, ScyllaEvent e2) {
                return e1.getSimulationTimeOfSource().compareTo(e2.getSimulationTimeOfSource());
            }
        });
        ScyllaEvent event = eventCandidates.get(0);
        // get and assign resources
        ResourceObjectTuple resourcesObjectTuple = getResourcesForEvent(model, event);
        assignResourcesToEvent(model, event, resourcesObjectTuple);
        ProcessSimulationComponents desmojObjects = event.getDesmojObjects();
        int nodeId = event.getNodeId();
        Set<ResourceReference> resourceReferences = desmojObjects.getSimulationConfiguration().getResourceReferenceSet(nodeId);
        for (ResourceReference ref : resourceReferences) {
            // remove from event queues
            String resourceId = ref.getResourceId();
            ScyllaEventQueue eventQueue = model.getEventQueues().get(resourceId);
            eventQueue.remove(event);
        }
        return event;
    }
}
Also used : ArrayList(java.util.ArrayList) ScyllaEvent(de.hpi.bpt.scylla.simulation.event.ScyllaEvent) ResourceReference(de.hpi.bpt.scylla.model.configuration.ResourceReference)

Example 20 with ScyllaEvent

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

the class QueueManager method releaseResourcesAndScheduleQueuedEvents.

/**
 * Releases the resource instances assigned to the given event, selects event(s) from the event queues which are due
 * next and schedules them immediately.
 *
 * @param model
 *            the simulation model
 * @param releasingEvent
 *            the DesmoJ event whose resource instances may be released
 * @throws ScyllaRuntimeException
 */
public static void releaseResourcesAndScheduleQueuedEvents(SimulationModel model, ScyllaEvent releasingEvent) throws ScyllaRuntimeException {
    ProcessInstance processInstance = releasingEvent.getProcessInstance();
    int nodeId = releasingEvent.getNodeId();
    String nameOfResponsibleEvent = releasingEvent.getSource();
    // release resources
    Set<String> resourceQueuesUpdated = new HashSet<String>();
    Set<ResourceObject> assignedResources = new HashSet<ResourceObject>();
    if (nameOfResponsibleEvent == null) {
        // release all resources of process instance
        for (ResourceObjectTuple tuple : processInstance.getAssignedResources().values()) {
            assignedResources.addAll(tuple.getResourceObjects());
        }
    } else {
        assignedResources.addAll(processInstance.getAssignedResources().get(nameOfResponsibleEvent).getResourceObjects());
    }
    Map<String, ResourceQueue> resourceObjects = model.getResourceObjects();
    TimeInstant presentTime = model.presentTime();
    for (ResourceObject resourceObject : assignedResources) {
        String resourceId = resourceObject.getResourceType();
        resourceObjects.get(resourceId).offer(presentTime, resourceObject, processInstance, nodeId);
        String traceNote = "Dissociate resource " + resourceId + " (" + resourceObject.getId() + ") from process instance " + processInstance.getName();
        if (nameOfResponsibleEvent != null) {
            traceNote += ", source: " + nameOfResponsibleEvent;
        }
        model.sendTraceNote(traceNote);
        resourceQueuesUpdated.add(resourceId);
    }
    if (nameOfResponsibleEvent == null) {
        processInstance.getAssignedResources().clear();
    } else {
        processInstance.getAssignedResources().remove(nameOfResponsibleEvent);
    }
    // ... and schedule next task if there are any in the queue
    /**
     * there may be no event ready for schedule, especially if they rely on resources that are together not
     * available at the moment, so we have to check "later" again ? (whatever later means)
     *
     * --> solved by introduction of ResourceAvailableEvent
     */
    ScyllaEvent eventFromQueue = getEventFromQueueReadyForSchedule(model, resourceQueuesUpdated);
    while (eventFromQueue != null) {
        SimulationUtils.scheduleEvent(eventFromQueue, new TimeSpan(0));
        eventFromQueue = getEventFromQueueReadyForSchedule(model, resourceQueuesUpdated);
    }
}
Also used : ScyllaEvent(de.hpi.bpt.scylla.simulation.event.ScyllaEvent) TimeSpan(desmoj.core.simulator.TimeSpan) TimeInstant(desmoj.core.simulator.TimeInstant) HashSet(java.util.HashSet)

Aggregations

ScyllaEvent (de.hpi.bpt.scylla.simulation.event.ScyllaEvent)21 ProcessModel (de.hpi.bpt.scylla.model.process.ProcessModel)15 TimeSpan (desmoj.core.simulator.TimeSpan)15 NodeNotFoundException (de.hpi.bpt.scylla.model.process.graph.exception.NodeNotFoundException)7 ProcessInstance (de.hpi.bpt.scylla.simulation.ProcessInstance)7 SimulationModel (de.hpi.bpt.scylla.simulation.SimulationModel)7 ProcessSimulationComponents (de.hpi.bpt.scylla.simulation.ProcessSimulationComponents)6 ArrayList (java.util.ArrayList)6 ScyllaValidationException (de.hpi.bpt.scylla.exception.ScyllaValidationException)5 ScyllaRuntimeException (de.hpi.bpt.scylla.exception.ScyllaRuntimeException)4 TaskTerminateEvent (de.hpi.bpt.scylla.simulation.event.TaskTerminateEvent)4 TimeInstant (desmoj.core.simulator.TimeInstant)4 BPMNStartEvent (de.hpi.bpt.scylla.simulation.event.BPMNStartEvent)3 HashSet (java.util.HashSet)3 Map (java.util.Map)3 MultipleStartNodesException (de.hpi.bpt.scylla.model.process.graph.exception.MultipleStartNodesException)2 NoStartNodeException (de.hpi.bpt.scylla.model.process.graph.exception.NoStartNodeException)2 EventDefinitionType (de.hpi.bpt.scylla.model.process.node.EventDefinitionType)2 GatewayType (de.hpi.bpt.scylla.model.process.node.GatewayType)2 TaskBeginEvent (de.hpi.bpt.scylla.simulation.event.TaskBeginEvent)2