use of de.hpi.bpt.scylla.simulation.ProcessInstance in project scylla by bptlab.
the class ProcessSimulationStopEvent method eventRoutine.
@Override
public void eventRoutine() throws SuspendExecution {
SimulationModel model = (SimulationModel) getModel();
Set<Integer> idsOfProcessInstancesToAbort = QueueManager.clearEventQueuesByProcessId(model, processId);
try {
ProcessSimulationStopEventPluggable.runPlugins(this);
// we do not have any submodels
boolean includeSubmodels = false;
List<Entity> entities = model.getEntities(includeSubmodels);
for (Entity entity : entities) {
if (entity instanceof ProcessInstance) {
ProcessInstance processInstance = (ProcessInstance) entity;
if (processInstance.isScheduled() && processId.equals(processInstance.getProcessModel().getId())) {
processInstance.cancel();
idsOfProcessInstancesToAbort.add(processInstance.getId());
}
} else {
DebugLogger.log("Found unsupported DesmoJ entity: " + entity.getName());
}
}
for (Integer id : idsOfProcessInstancesToAbort) {
DebugLogger.log("Abort process instance " + id + " of process " + processId + ".");
}
if (idsOfProcessInstancesToAbort.size() > 0) {
DebugLogger.log("End time of process " + processId + " reached.");
}
if (model.getEndDateTime() != null) {
long currentTime = model.presentTime().getTimeRounded(DateTimeUtils.getReferenceTimeUnit());
long simulationEndTime = DateTimeUtils.getDuration(model.getStartDateTime(), model.getEndDateTime());
if (simulationEndTime == currentTime) {
model.getExperiment().stop(new TimeInstant(currentTime + 1));
}
}
} catch (ScyllaRuntimeException e) {
throw new RuntimeException(e);
}
}
use of de.hpi.bpt.scylla.simulation.ProcessInstance in project scylla by bptlab.
the class SimulationUtils method scheduleEvent.
/**
* Schedules given DesmoJ event.
*
* @param model
* the simulation model which the event is attached to
* @param processInstance
* the entity which the event is scheduled for
* @param processInstanceId
* the identifier of the process instance (= entity)
* @param event
* the DesmoJ event to be scheduled
* @param timeSpan
* the time which the event is scheduled for, relatively to the simulation time
* @throws SuspendExecution
* @throws ScyllaRuntimeException
*/
public static void scheduleEvent(ScyllaEvent event, TimeSpan timeSpan) throws ScyllaRuntimeException {
boolean normalBehavior = EventSchedulingPluggable.runPlugins(event, timeSpan);
if (normalBehavior) {
ProcessInstance processInstance = event.getProcessInstance();
event.schedule(processInstance, timeSpan);
}
}
use of de.hpi.bpt.scylla.simulation.ProcessInstance in project scylla by bptlab.
the class BPMNEscalationBPMNEEPlugin 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.ESCALATION) {
if (processModel.getParent() != null) {
Map<String, String> eventAttributes = processModel.getEventDefinitions().get(nodeId).get(definition);
String escalationRef = eventAttributes.get("escalationRef");
// Map<String, Map<String, String>> escalations =
// model.getCommonProcessElements().getEscalations();
// Map<String, String> escalation = escalations.get("escalationRef");
ProcessSimulationComponents parentDesmojObjects = desmojObjects.getParent();
ProcessModel parentModel = processModel.getParent();
int nodeIdInParent = processModel.getNodeIdInParent();
Integer nextNodeId = null;
// find boundary event of parentModel which has the same escalationRef
List<Integer> referencesToBoundaryEvents = parentModel.getReferencesToBoundaryEvents().get(nodeIdInParent);
for (int nId : referencesToBoundaryEvents) {
Map<EventDefinitionType, Map<String, String>> boundaryEventDefinitions = parentModel.getEventDefinitions().get(nId);
Map<String, String> boundaryEscalationEventDefinition = boundaryEventDefinitions.get(EventDefinitionType.ESCALATION);
if (boundaryEscalationEventDefinition != null) {
if (escalationRef.equals(boundaryEscalationEventDefinition.get("escalationRef"))) {
nextNodeId = nId;
break;
}
}
}
if (nextNodeId == null) {
DebugLogger.error("Could not find referenced escalation " + escalationRef + ".");
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);
}
}
use of de.hpi.bpt.scylla.simulation.ProcessInstance 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;
}
use of de.hpi.bpt.scylla.simulation.ProcessInstance 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);
}
}
}
Aggregations