mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Refactor workflow cancellation logic to encapsulate transition checks in a dedicated method, and update CronJob handling to use entity workflows instead of IDs. Enhance test coverage to ensure proper handling and instantiate mocks for EntityManagerInterface.
77 lines
2.6 KiB
PHP
77 lines
2.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* Chill is a software for social workers
|
|
*
|
|
* For the full copyright and license information, please view
|
|
* the LICENSE file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Chill\MainBundle\Service\Workflow;
|
|
|
|
use Chill\MainBundle\Cron\CronJobInterface;
|
|
use Chill\MainBundle\Entity\CronJobExecution;
|
|
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Psr\Log\LoggerInterface;
|
|
use Symfony\Component\Clock\ClockInterface;
|
|
use Symfony\Component\Messenger\MessageBusInterface;
|
|
|
|
class CancelStaleWorkflowCronJob implements CronJobInterface
|
|
{
|
|
public const KEY = 'remove-stale-workflow';
|
|
|
|
public const KEEP_INTERVAL = 'P90D';
|
|
|
|
private const LAST_CANCELED_WORKFLOW = 'last-canceled-workflow-id';
|
|
|
|
public function __construct(
|
|
private readonly EntityWorkflowRepository $workflowRepository,
|
|
private readonly ClockInterface $clock,
|
|
private readonly MessageBusInterface $messageBus,
|
|
private readonly LoggerInterface $logger,
|
|
private readonly EntityManagerInterface $entityManager,
|
|
) {}
|
|
|
|
public function canRun(?CronJobExecution $cronJobExecution): bool
|
|
{
|
|
return $this->clock->now() >= $cronJobExecution->getLastEnd()->add(new \DateInterval('P1D'));
|
|
}
|
|
|
|
public function getKey(): string
|
|
{
|
|
return self::KEY;
|
|
}
|
|
|
|
public function run(array $lastExecutionData): ?array
|
|
{
|
|
$this->logger->info('Cronjob started: Canceling stale workflows.');
|
|
|
|
$olderThanDate = $this->clock->now()->sub(new \DateInterval(self::KEEP_INTERVAL));
|
|
$staleEntityWorkflows = $this->workflowRepository->findWorkflowsWithoutFinalStepAndOlderThan($olderThanDate);
|
|
$lastCanceled = $lastExecutionData[self::LAST_CANCELED_WORKFLOW] ?? 0;
|
|
$processedCount = 0;
|
|
|
|
foreach ($staleEntityWorkflows as $staleEntityWorkflow) {
|
|
try {
|
|
$this->messageBus->dispatch(new CancelStaleWorkflowMessage($staleEntityWorkflow->getId()));
|
|
$lastCanceled = max($staleEntityWorkflow->getId(), $lastCanceled);
|
|
++$processedCount;
|
|
} catch (\Exception $e) {
|
|
$this->logger->error('Failed to dispatch CancelStaleWorkflow', ['exception' => $e, 'entityWorkflowId' => $staleEntityWorkflow->getId()]);
|
|
continue;
|
|
}
|
|
|
|
if (0 === $processedCount % 10) {
|
|
$this->entityManager->clear();
|
|
}
|
|
}
|
|
|
|
$this->logger->info("Cronjob completed: {$processedCount} workflows processed.");
|
|
|
|
return [self::LAST_CANCELED_WORKFLOW => $lastCanceled];
|
|
}
|
|
}
|