getTargetId() ?? throw new RuntimeException(); $process = $this->getProcess($processId); if (!$process) { return; } $this->bpmnManager->processPendingFlows($processId); $this->updateProcess($processId); } private function updateProcess(string $processId): void { $process = $this->entityManager->getRDBRepositoryByClass(BpmnProcess::class)->getById($processId); if (!$process) { return; } // If the job was running for long, this will ensure the process won't be processed // too soon the next time. $process->setVisitTimestampNow(); $process->setIsLocked(false); $this->entityManager->saveEntity($process, [SaveOption::SKIP_ALL => true]); } private function getProcess(string $processId): ?BpmnProcess { $this->entityManager->getTransactionManager()->start(); $process = $this->entityManager ->getRDBRepositoryByClass(BpmnProcess::class) ->forUpdate() ->where(['id' => $processId]) ->findOne(); if (!$process) { $this->entityManager->getTransactionManager()->commit(); return null; } if (!$process->isLocked()) { // Can happen if jobs were not running for long and the process got unlocked. throw new RuntimeException("BPM: Process $processId is not locked."); } // If the job ran late, this will prevent the process from unlocking while it's being processed. $process->setVisitTimestampNow(); $this->entityManager->saveEntity($process, [SaveOption::SKIP_ALL => true]); $this->entityManager->getTransactionManager()->commit(); return $process; } }