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);
}
}
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);
}
}
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));
}
}
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);
}
}
Aggregations