[cron expression, description] */ private const TASKS = [ 'vitec:ssr-health' => [ '*/5 * * * *', 'SSR health check: samples /__health and /__stats of the SSR node into the health log (cockpit charts), ' . 'mails the alert recipients from Site settings › VITEC on down/up changes and falls back to the SPA ' . 'after repeated failures. Formerly crontab.', ], 'vitec:client-error-cleanup' => [ '23 4 * * *', 'Deletes browser error reports (client errors from the React frontend) older than 30 days. Formerly crontab.', ], ]; public function __construct( private readonly TaskService $taskService, private readonly SchedulerTaskRepository $taskRepository, private readonly ConnectionPool $connectionPool, ) { parent::__construct(); } protected function configure(): void { $this->addOption('disabled', null, InputOption::VALUE_NONE, 'Create new tasks switched off'); $this->addOption('enable', null, InputOption::VALUE_NONE, 'Switch on all VITEC tasks created by this command'); } protected function execute(InputInterface $input, OutputInterface $output): int { Bootstrap::initializeBackendAuthentication(); $groupUid = $this->groupUid(); $output->writeln('Scheduler group "' . self::GROUP . '": uid ' . $groupUid); foreach (self::TASKS as $command => [$cron, $description]) { $existing = $this->findTask($command); if ($existing !== null) { if ($input->getOption('enable') && (int)$existing['disable'] === 1) { $task = $this->taskRepository->findByUid((int)$existing['uid']); $task->setDisabled(false); $this->taskRepository->update($task); $output->writeln(sprintf('%s: enabled (uid %d)', $command, $existing['uid'])); } else { $output->writeln(sprintf('%s: exists (uid %d, %s)', $command, $existing['uid'], (int)$existing['disable'] === 1 ? 'disabled' : 'enabled')); } continue; } if (!$this->taskService->isTaskTypeRegistered($command)) { $output->writeln('' . $command . ': not available as scheduler task type'); continue; } $task = $this->taskService->createNewTask($command); $task->setDescription($description); $task->setTaskGroup($groupUid); $task->setExecution(Execution::createRecurringExecution(time() - 60, 0, 0, false, $cron)); $task->setDisabled((bool)$input->getOption('disabled')); if ($this->taskRepository->add($task)) { $output->writeln(sprintf('%s: created (uid %d, %s, %s)', $command, $task->getTaskUid(), $cron, $task->isDisabled() ? 'disabled' : 'enabled')); } else { $output->writeln('' . $command . ': could not be created'); } } return Command::SUCCESS; } private function groupUid(): int { $connection = $this->connectionPool->getConnectionForTable('tx_scheduler_task_group'); $uid = $connection->executeQuery( 'SELECT uid FROM tx_scheduler_task_group WHERE groupName = ? AND deleted = 0 ORDER BY uid LIMIT 1', [self::GROUP] )->fetchOne(); if ($uid !== false) { return (int)$uid; } $sorting = (int)$connection->executeQuery('SELECT MAX(sorting) FROM tx_scheduler_task_group')->fetchOne(); $connection->insert('tx_scheduler_task_group', [ 'pid' => 0, 'tstamp' => time(), 'crdate' => time(), 'groupName' => self::GROUP, 'color' => '#f47937', 'description' => 'Recurring jobs of the VITEC website (SSR monitoring, cleanups)', 'sorting' => $sorting + 256, ], ['pid' => Connection::PARAM_INT, 'tstamp' => Connection::PARAM_INT, 'crdate' => Connection::PARAM_INT, 'sorting' => Connection::PARAM_INT]); return (int)$connection->lastInsertId(); } private function findTask(string $command): ?array { $row = $this->connectionPool->getConnectionForTable('tx_scheduler_task')->executeQuery( 'SELECT uid, disable FROM tx_scheduler_task WHERE tasktype = ? AND deleted = 0 ORDER BY uid LIMIT 1', [$command] )->fetchAssociative(); return $row === false ? null : $row; } }