/** * {@inheritdoc} */ public function execute(Execution $execution) { $execution->getEngine()->notify(new ActivityStartedEvent($this->activityId, $execution, $execution->getEngine())); $execution->getEngine()->info('ENTER: scope <{scope}> at level {level} using {execution}', ['scope' => $this->activityId, 'level' => $execution->getExecutionDepth(), 'execution' => (string) $execution]); $root = $execution->createNestedExecution($execution->getProcessModel(), $execution->getNode(), true); $root->waitForSignal(); $this->createEventSubscriptions($root, $this->activityId, $execution->getNode()); $this->enter($root->createExecution(false)); }
/** * {@inheritdoc} */ public function execute(Execution $execution) { foreach ($execution->getProcessModel()->findOutgoingTransitions($execution->getNode()->getId()) as $trans) { if ($trans->getId() === $this->defaultTransition) { continue; } if ($trans->isEnabled($execution)) { return $execution->take($trans); } } if ($this->defaultTransition !== NULL) { return $execution->take($this->defaultTransition); } $message = sprintf('Execution %s about to get stuck in exclusive choice within node "%s"', $execution->getId(), $execution->getNode()->getId()); throw new StuckException($message); }
protected function isReachable(Node $source, Node $target, Execution $execution, \SplObjectStorage $visited) { if ($source === $target) { return true; } $model = $execution->getProcessModel(); $out = $model->findOutgoingTransitions($source->getId()); $visited->attach($source); foreach ($out as $transition) { $tmp = $model->findNode($transition->getTo()); if (!$visited->contains($tmp) && $this->isReachable($tmp, $target, $execution, $visited)) { return true; } } return false; }
/** * {@inheritdoc} */ public function execute(Execution $execution) { $execution->setActive(false); $numberExecutions = count($execution->getProcessModel()->findIncomingTransitions($execution->getNode()->getId())); // Collect recycled executions, initialize with current execution: $recycle = [$execution->getTransition()->getId() => $execution]; foreach ($execution->findInactiveConcurrentExecutions($execution->getNode()) as $concurrent) { // Collect at most 1 execution per incoming transition. $transId = $concurrent->getTransition()->getId(); if (empty($recycle[$transId]) || $concurrent->getTimestamp() < $recycle[$transId]->getTimestamp()) { $recycle[$transId] = $concurrent; } } if (count($recycle) !== $numberExecutions) { return; } return $execution->takeAll(NULL, $recycle); }
/** * Find the outgoing transition to be taken by the given execution. * * @param Execution $execution * @throws \RuntimeException * @return Transition */ protected function findTransition(Execution $execution) { $out = (array) $execution->getProcessModel()->findOutgoingTransitions($execution->getNode()->getId()); $trans = NULL; if ($this->transitionId === NULL) { if (count($out) != 1) { throw new \RuntimeException(sprintf('No single outgoing transition found at node "%s"', $execution->getNode()->getId())); } return array_pop($out); } foreach ($out as $tmp) { if ($tmp->getId() === $this->transitionId) { $trans = $tmp; break; } } if ($trans === NULL) { throw new \RuntimeException(sprintf('Transition "%s" not connected to node "%s"', $this->transitionId, $execution->getNode()->getId())); } return $trans; }