src/Core/Framework/MessageQueue/ScheduledTask/ScheduledTaskHandler.php line 83

  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Framework\MessageQueue\ScheduledTask;
  3. use Shopware\Core\Defaults;
  4. use Shopware\Core\Framework\Context;
  5. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  6. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  7. use Shopware\Core\Framework\Log\Package;
  8. use Symfony\Component\Messenger\Attribute\AsMessageHandler;
  9. use Symfony\Component\Messenger\Handler\MessageSubscriberInterface;
  10. /**
  11.  * @deprecated tag:v6.6.0 - reason:class-hierarchy-change - Won't implement MessageSubscriberInterface anymore, tag all ScheduledTaskHandlers with #[AsMessageHandler] instead
  12.  */
  13. #[Package('core')]
  14. abstract class ScheduledTaskHandler implements MessageSubscriberInterface
  15. {
  16.     protected EntityRepository $scheduledTaskRepository;
  17.     public function __construct(EntityRepository $scheduledTaskRepository)
  18.     {
  19.         $this->scheduledTaskRepository $scheduledTaskRepository;
  20.     }
  21.     public function __invoke(ScheduledTask $task): void
  22.     {
  23.         $taskId $task->getTaskId();
  24.         if ($taskId === null) {
  25.             // run task independent of the schedule
  26.             $this->run();
  27.             return;
  28.         }
  29.         /** @var ScheduledTaskEntity|null $taskEntity */
  30.         $taskEntity $this->scheduledTaskRepository
  31.             ->search(new Criteria([$taskId]), Context::createDefaultContext())
  32.             ->get($taskId);
  33.         if ($taskEntity === null || !$taskEntity->isExecutionAllowed()) {
  34.             return;
  35.         }
  36.         $this->markTaskRunning($task);
  37.         try {
  38.             $this->run();
  39.         } catch (\Throwable $e) {
  40.             $this->markTaskFailed($task);
  41.             throw $e;
  42.         }
  43.         $this->rescheduleTask($task$taskEntity);
  44.     }
  45.     /**
  46.      * @deprecated tag:v6.6.0 - reason:class-hierarchy-change - method will be removed, tag all ScheduledTaskHandlers with #[AsMessageHandler] instead
  47.      *
  48.      * @return iterable<string>
  49.      */
  50.     public static function getHandledMessages(): iterable
  51.     {
  52.         $reflection = new \ReflectionClass(static::class);
  53.         $attributes $reflection->getAttributes(AsMessageHandler::class);
  54.         $messageClasses = [];
  55.         foreach ($attributes as $attribute) {
  56.             /** @var AsMessageHandler $messageAttribute */
  57.             $messageAttribute $attribute->newInstance();
  58.             $messageClasses[] = $messageAttribute->handles;
  59.         }
  60.         return array_filter($messageClasses);
  61.     }
  62.     abstract public function run(): void;
  63.     protected function markTaskRunning(ScheduledTask $task): void
  64.     {
  65.         $this->scheduledTaskRepository->update([
  66.             [
  67.                 'id' => $task->getTaskId(),
  68.                 'status' => ScheduledTaskDefinition::STATUS_RUNNING,
  69.             ],
  70.         ], Context::createDefaultContext());
  71.     }
  72.     protected function markTaskFailed(ScheduledTask $task): void
  73.     {
  74.         $this->scheduledTaskRepository->update([
  75.             [
  76.                 'id' => $task->getTaskId(),
  77.                 'status' => ScheduledTaskDefinition::STATUS_FAILED,
  78.             ],
  79.         ], Context::createDefaultContext());
  80.     }
  81.     protected function rescheduleTask(ScheduledTask $taskScheduledTaskEntity $taskEntity): void
  82.     {
  83.         $now = new \DateTimeImmutable();
  84.         $nextExecutionTimeString $taskEntity->getNextExecutionTime()->format(Defaults::STORAGE_DATE_TIME_FORMAT);
  85.         $nextExecutionTime = new \DateTimeImmutable($nextExecutionTimeString);
  86.         $newNextExecutionTime $nextExecutionTime->modify(sprintf('+%d seconds'$taskEntity->getRunInterval()));
  87.         if ($newNextExecutionTime $now) {
  88.             $newNextExecutionTime $now;
  89.         }
  90.         $this->scheduledTaskRepository->update([
  91.             [
  92.                 'id' => $task->getTaskId(),
  93.                 'status' => ScheduledTaskDefinition::STATUS_SCHEDULED,
  94.                 'lastExecutionTime' => $now,
  95.                 'nextExecutionTime' => $newNextExecutionTime,
  96.             ],
  97.         ], Context::createDefaultContext());
  98.     }
  99. }