Files
kupshop/bundles/KupShop/SynchronizationBundle/Command/SynchronizationHealthStatusCommand.php
2025-08-02 16:30:27 +02:00

85 lines
3.2 KiB
PHP

<?php
declare(strict_types=1);
namespace KupShop\SynchronizationBundle\Command;
use KupShop\KupShopBundle\Util\Logging\SentryLogger;
use KupShop\SynchronizationBundle\Exception\SynchronizationException;
use KupShop\SynchronizationBundle\Util\SynchronizationJobProvider;
use KupShop\SynchronizationBundle\Util\SynchronizationQueueUtil;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Contracts\Service\Attribute\Required;
#[AsCommand(name: 'kupshop:synchronization:health', description: 'Returns if synchronization is healthy. This command is used by synchronization pod so pod is restarted when not healthy.')]
class SynchronizationHealthStatusCommand extends Command
{
private SynchronizationQueueUtil $queueUtil;
private SynchronizationJobProvider $jobProvider;
private SentryLogger $sentryLogger;
#[Required]
final public function setSynchronizationQueueUtil(SynchronizationQueueUtil $queueUtil): void
{
$this->queueUtil = $queueUtil;
}
#[Required]
final public function setSynchronizationJobProvider(SynchronizationJobProvider $jobProvider): void
{
$this->jobProvider = $jobProvider;
}
#[Required]
final public function setSentryLogger(SentryLogger $sentryLogger): void
{
$this->sentryLogger = $sentryLogger;
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$runningJobs = array_filter($this->queueUtil->getJobStatuses(), fn (array $x) => $x['status'] === SynchronizationQueueUtil::STATUS_RUNNING);
foreach ($runningJobs as $jobId => $jobInfo) {
if (!($job = $this->jobProvider->getJob($jobId))) {
continue;
}
// skip jobs with no execution time limit
if ($job->maxExecutionTime === null) {
continue;
}
// job is running more than maximum execution time, so return error code so synchronization pod is going to be restarted
if ((time() - $jobInfo['time']) > ($job->maxExecutionTime * 60)) {
// update job status
$this->queueUtil->setJobStatus(
$jobId,
SynchronizationQueueUtil::STATUS_FAILED,
"Job exceeded maximum execution time limit - {$job->maxExecutionTime} minutes"
);
// send notification to Sentry so we know about jobs that timed out
$this->sentryLogger->captureException(
new SynchronizationException(
"Job \"{$job->name}\" exceeded maximum execution time limit!",
[
'jobName' => $job->name,
'jobMaxExecutionTime' => $job->maxExecutionTime,
]
)
);
// return error code - timeout (error status) so livenessProbe is going to restart synchronization pod
return 124;
}
}
// return 0 as success (ok status)
return 0;
}
}