use of org.activiti.engine.impl.pvm.delegate.ActivityExecution in project Activiti by Activiti.
the class ParallelGatewayActivityBehavior method execute.
public void execute(ActivityExecution execution) throws Exception {
// Join
PvmActivity activity = execution.getActivity();
List<PvmTransition> outgoingTransitions = execution.getActivity().getOutgoingTransitions();
execution.inactivate();
lockConcurrentRoot(execution);
List<ActivityExecution> joinedExecutions = execution.findInactiveConcurrentExecutions(activity);
int nbrOfExecutionsToJoin = execution.getActivity().getIncomingTransitions().size();
int nbrOfExecutionsJoined = joinedExecutions.size();
Context.getCommandContext().getHistoryManager().recordActivityEnd((ExecutionEntity) execution);
if (nbrOfExecutionsJoined == nbrOfExecutionsToJoin) {
// Fork
if (log.isDebugEnabled()) {
log.debug("parallel gateway '{}' activates: {} of {} joined", activity.getId(), nbrOfExecutionsJoined, nbrOfExecutionsToJoin);
}
execution.takeAll(outgoingTransitions, joinedExecutions);
} else if (log.isDebugEnabled()) {
log.debug("parallel gateway '{}' does not activate: {} of {} joined", activity.getId(), nbrOfExecutionsJoined, nbrOfExecutionsToJoin);
}
}
use of org.activiti.engine.impl.pvm.delegate.ActivityExecution in project Activiti by Activiti.
the class ParallelMultiInstanceBehavior method leave.
/**
* Called when the wrapped {@link ActivityBehavior} calls the
* {@link AbstractBpmnActivityBehavior#leave(ActivityExecution)} method.
* Handles the completion of one of the parallel instances
*/
public void leave(ActivityExecution execution) {
callActivityEndListeners(execution);
int nrOfInstances = getLoopVariable(execution, NUMBER_OF_INSTANCES);
if (nrOfInstances == 0) {
// Empty collection, just leave.
super.leave(execution);
return;
}
int loopCounter = getLoopVariable(execution, getCollectionElementIndexVariable());
int nrOfCompletedInstances = getLoopVariable(execution, NUMBER_OF_COMPLETED_INSTANCES) + 1;
int nrOfActiveInstances = getLoopVariable(execution, NUMBER_OF_ACTIVE_INSTANCES) - 1;
if (isExtraScopeNeeded()) {
// In case an extra scope was created, it must be destroyed first before going further
ExecutionEntity extraScope = (ExecutionEntity) execution;
execution = execution.getParent();
extraScope.remove();
}
if (execution.getParent() != null) {
// will be null in case of empty collection
setLoopVariable(execution.getParent(), NUMBER_OF_COMPLETED_INSTANCES, nrOfCompletedInstances);
setLoopVariable(execution.getParent(), NUMBER_OF_ACTIVE_INSTANCES, nrOfActiveInstances);
}
logLoopDetails(execution, "instance completed", loopCounter, nrOfCompletedInstances, nrOfActiveInstances, nrOfInstances);
ExecutionEntity executionEntity = (ExecutionEntity) execution;
if (executionEntity.getParent() != null) {
executionEntity.inactivate();
executionEntity.getParent().forceUpdate();
List<ActivityExecution> joinedExecutions = executionEntity.findInactiveConcurrentExecutions(execution.getActivity());
if (joinedExecutions.size() >= nrOfInstances || completionConditionSatisfied(execution)) {
// Removing all active child executions (ie because completionCondition is true)
List<ExecutionEntity> executionsToRemove = new ArrayList<ExecutionEntity>();
for (ActivityExecution childExecution : executionEntity.getParent().getExecutions()) {
if (childExecution.isActive()) {
executionsToRemove.add((ExecutionEntity) childExecution);
}
}
for (ExecutionEntity executionToRemove : executionsToRemove) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Execution {} still active, but multi-instance is completed. Removing this execution.", executionToRemove);
}
executionToRemove.inactivate();
executionToRemove.deleteCascade("multi-instance completed");
}
executionEntity.takeAll(executionEntity.getActivity().getOutgoingTransitions(), joinedExecutions);
}
} else {
super.leave(executionEntity);
}
}
use of org.activiti.engine.impl.pvm.delegate.ActivityExecution in project Activiti by Activiti.
the class AbstractBpmnActivityBehavior method signalCompensationDone.
protected void signalCompensationDone(ActivityExecution execution, Object signalData) {
// join compensating executions
if (execution.getExecutions().isEmpty()) {
if (execution.getParent() != null) {
ActivityExecution parent = execution.getParent();
((InterpretableExecution) execution).remove();
((InterpretableExecution) parent).signal("compensationDone", signalData);
}
} else {
((ExecutionEntity) execution).forceUpdate();
}
}
use of org.activiti.engine.impl.pvm.delegate.ActivityExecution in project Activiti by Activiti.
the class CancelEndEventActivityBehavior method execute.
@Override
public void execute(ActivityExecution execution) throws Exception {
// find cancel boundary event:
ActivityImpl cancelBoundaryEvent = ScopeUtil.findInParentScopesByBehaviorType((ActivityImpl) execution.getActivity(), CancelBoundaryEventActivityBehavior.class);
if (cancelBoundaryEvent == null) {
throw new ActivitiException("Could not find cancel boundary event for cancel end event " + execution.getActivity());
}
ActivityExecution scopeExecution = ScopeUtil.findScopeExecutionForScope((ExecutionEntity) execution, cancelBoundaryEvent.getParentActivity());
// end all executions and process instances in the scope of the transaction
scopeExecution.destroyScope("cancel end event fired");
// the scope execution executes the boundary event
InterpretableExecution outgoingExecution = (InterpretableExecution) scopeExecution;
outgoingExecution.setActivity(cancelBoundaryEvent);
outgoingExecution.setActive(true);
// execute the boundary
cancelBoundaryEvent.getActivityBehavior().execute(outgoingExecution);
}
use of org.activiti.engine.impl.pvm.delegate.ActivityExecution in project Activiti by Activiti.
the class ExecutionEntity method takeAll.
@SuppressWarnings({ "unchecked", "rawtypes" })
public void takeAll(List<PvmTransition> transitions, List<ActivityExecution> recyclableExecutions) {
fireActivityCompletedEvent();
transitions = new ArrayList<PvmTransition>(transitions);
recyclableExecutions = (recyclableExecutions != null ? new ArrayList<ActivityExecution>(recyclableExecutions) : new ArrayList<ActivityExecution>());
if (recyclableExecutions.size() > 1) {
for (ActivityExecution recyclableExecution : recyclableExecutions) {
if (((ExecutionEntity) recyclableExecution).isScope()) {
throw new PvmException("joining scope executions is not allowed");
}
}
}
ExecutionEntity concurrentRoot = ((isConcurrent && !isScope) ? getParent() : this);
List<ExecutionEntity> concurrentActiveExecutions = new ArrayList<ExecutionEntity>();
List<ExecutionEntity> concurrentInActiveExecutions = new ArrayList<ExecutionEntity>();
for (ExecutionEntity execution : concurrentRoot.getExecutions()) {
if (execution.isActive()) {
concurrentActiveExecutions.add(execution);
} else {
concurrentInActiveExecutions.add(execution);
}
}
if (log.isDebugEnabled()) {
log.debug("transitions to take concurrent: {}", transitions);
log.debug("active concurrent executions: {}", concurrentActiveExecutions);
}
if ((transitions.size() == 1) && (concurrentActiveExecutions.isEmpty()) && allExecutionsInSameActivity(concurrentInActiveExecutions)) {
List<ExecutionEntity> recyclableExecutionImpls = (List) recyclableExecutions;
recyclableExecutions.remove(concurrentRoot);
for (ExecutionEntity prunedExecution : recyclableExecutionImpls) {
// End the pruned executions if necessary.
// Some recyclable executions are inactivated (joined executions)
// Others are already ended (end activities)
// Need to call the activity end here. If we would do it later,
// the executions are removed and the historic activity instances are
// never ended as the combination of {activityId,executionId} is not valid anymor
Context.getCommandContext().getHistoryManager().recordActivityEnd(prunedExecution);
log.debug("pruning execution {}", prunedExecution);
prunedExecution.remove();
}
log.debug("activating the concurrent root {} as the single path of execution going forward", concurrentRoot);
concurrentRoot.setActive(true);
concurrentRoot.setActivity(activity);
concurrentRoot.setConcurrent(false);
concurrentRoot.take(transitions.get(0), false);
} else {
List<OutgoingExecution> outgoingExecutions = new ArrayList<OutgoingExecution>();
recyclableExecutions.remove(concurrentRoot);
log.debug("recyclable executions for reuse: {}", recyclableExecutions);
// first create the concurrent executions
while (!transitions.isEmpty()) {
PvmTransition outgoingTransition = transitions.remove(0);
ExecutionEntity outgoingExecution = null;
if (recyclableExecutions.isEmpty()) {
outgoingExecution = concurrentRoot.createExecution();
log.debug("new {} with parent {} created to take transition {}", outgoingExecution, outgoingExecution.getParent(), outgoingTransition);
} else {
outgoingExecution = (ExecutionEntity) recyclableExecutions.remove(0);
log.debug("recycled {} to take transition {}", outgoingExecution, outgoingTransition);
}
outgoingExecution.setActive(true);
outgoingExecution.setScope(false);
outgoingExecution.setConcurrent(true);
outgoingExecution.setTransitionBeingTaken((TransitionImpl) outgoingTransition);
outgoingExecutions.add(new OutgoingExecution(outgoingExecution, outgoingTransition, true));
}
// prune the executions that are not recycled
for (ActivityExecution prunedExecution : recyclableExecutions) {
log.debug("pruning execution {}", prunedExecution);
prunedExecution.end();
}
// then launch all the concurrent executions
for (OutgoingExecution outgoingExecution : outgoingExecutions) {
outgoingExecution.take(false);
}
}
}
Aggregations