harden semantic match sby tags

This commit is contained in:
team2
2026-02-28 19:22:42 +01:00
parent 1b5cff1c53
commit 03e7cfdeef

View File

@@ -12,11 +12,12 @@ use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
#[AsCommand( #[AsCommand(
name: 'mto:agent:tags:job:run', name: 'mto:agent:tags:job:run',
description: 'Run a single tag rebuild job (export tags.ndjson + build vector_tags.index) with lock' description: 'Run a tag rebuild job (export tags.ndjson + build vector_tags.index) with lock'
)] )]
final class TagRebuildRunJobCommand extends Command final class TagRebuildRunJobCommand extends Command
{ {
@@ -31,21 +32,42 @@ final class TagRebuildRunJobCommand extends Command
protected function configure(): void protected function configure(): void
{ {
$this->addArgument('jobId', InputArgument::REQUIRED, 'TagRebuildJob UUID'); $this
->addArgument('jobId', InputArgument::OPTIONAL, 'Existing TagRebuildJob UUID')
->addOption('create', null, InputOption::VALUE_NONE, 'Create and immediately run a new TagRebuildJob');
} }
protected function execute(InputInterface $input, OutputInterface $output): int protected function execute(InputInterface $input, OutputInterface $output): int
{ {
$jobId = (string) $input->getArgument('jobId'); $jobId = $input->getArgument('jobId');
$create = (bool) $input->getOption('create');
/** @var TagRebuildJob|null $job */ if (!$create && !$jobId) {
$job = $this->em->getRepository(TagRebuildJob::class)->find($jobId); $output->writeln('<error>You must provide either a jobId or use --create.</error>');
if (!$job instanceof TagRebuildJob) {
$output->writeln('<error>Job not found.</error>');
return Command::FAILURE; return Command::FAILURE;
} }
if ($create && $jobId) {
$output->writeln('<error>Use either jobId OR --create, not both.</error>');
return Command::FAILURE;
}
if ($create) {
$job = new TagRebuildJob();
$this->em->persist($job);
$this->em->flush();
$jobId = $job->getId();
$output->writeln('<info>Created new TagRebuildJob: ' . $jobId . '</info>');
} else {
/** @var TagRebuildJob|null $job */
$job = $this->em->getRepository(TagRebuildJob::class)->find($jobId);
if (!$job instanceof TagRebuildJob) {
$output->writeln('<error>Job not found.</error>');
return Command::FAILURE;
}
}
$fh = null; $fh = null;
try { try {
@@ -53,6 +75,7 @@ final class TagRebuildRunJobCommand extends Command
// LOCK INITIALIZATION // LOCK INITIALIZATION
// --------------------------------------------------------- // ---------------------------------------------------------
$lockDir = \dirname($this->lockFilePath); $lockDir = \dirname($this->lockFilePath);
if (!\is_dir($lockDir) && !@\mkdir($lockDir, 0775, true) && !\is_dir($lockDir)) { if (!\is_dir($lockDir) && !@\mkdir($lockDir, 0775, true) && !\is_dir($lockDir)) {
throw new \RuntimeException('Cannot create lock directory.'); throw new \RuntimeException('Cannot create lock directory.');
} }
@@ -85,7 +108,7 @@ final class TagRebuildRunJobCommand extends Command
throw new \RuntimeException('Export failed: NDJSON file missing.'); throw new \RuntimeException('Export failed: NDJSON file missing.');
} }
if (isset($export['count']) && (int)$export['count'] === 0) { if (isset($export['count']) && (int) $export['count'] === 0) {
throw new \RuntimeException('Export produced zero tags.'); throw new \RuntimeException('Export produced zero tags.');
} }
@@ -107,8 +130,10 @@ final class TagRebuildRunJobCommand extends Command
} }
catch (\Throwable $e) { catch (\Throwable $e) {
$job->markFailed($e->getMessage()); if (isset($job)) {
$this->em->flush(); $job->markFailed($e->getMessage());
$this->em->flush();
}
$output->writeln('<error>FAILED: ' . $e->getMessage() . '</error>'); $output->writeln('<error>FAILED: ' . $e->getMessage() . '</error>');