[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;
}
}