optimize tag and rebuilding

This commit is contained in:
team2
2026-02-23 08:51:21 +01:00
parent 8c58d6777d
commit dceeaeee52
8 changed files with 678 additions and 167 deletions

View File

@@ -36,68 +36,90 @@ final class TagRebuildRunJobCommand extends Command
protected function execute(InputInterface $input, OutputInterface $output): int
{
$jobId = (string)$input->getArgument('jobId');
$jobId = (string) $input->getArgument('jobId');
/** @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;
}
// ---------------------------------------------------------
// Global lock to avoid parallel rebuilds
// ---------------------------------------------------------
$lockDir = \dirname($this->lockFilePath);
if (!\is_dir($lockDir)) {
@\mkdir($lockDir, 0775, true);
}
$fh = @\fopen($this->lockFilePath, 'c+');
if (!$fh) {
$job->markFailed('Cannot open lock file: ' . $this->lockFilePath);
$this->em->flush();
$output->writeln('<error>Cannot open lock file.</error>');
return Command::FAILURE;
}
// If another rebuild runs, we fail fast (simple & safe).
if (!@\flock($fh, LOCK_EX | LOCK_NB)) {
\fclose($fh);
$job->markFailed('Another tag rebuild is currently running (lock busy).');
$this->em->flush();
$output->writeln('<error>Lock busy. Another rebuild is running.</error>');
return Command::FAILURE;
}
// mark running
$job->markRunning();
$this->em->flush();
$fh = null;
try {
// ---------------------------------------------------------
// LOCK INITIALIZATION
// ---------------------------------------------------------
$lockDir = \dirname($this->lockFilePath);
if (!\is_dir($lockDir) && !@\mkdir($lockDir, 0775, true) && !\is_dir($lockDir)) {
throw new \RuntimeException('Cannot create lock directory.');
}
$fh = @\fopen($this->lockFilePath, 'c+');
if (!$fh) {
throw new \RuntimeException('Cannot open lock file: ' . $this->lockFilePath);
}
if (!@\flock($fh, LOCK_EX | LOCK_NB)) {
throw new \RuntimeException('Another tag rebuild is currently running (lock busy).');
}
// ---------------------------------------------------------
// MARK RUNNING
// ---------------------------------------------------------
$job->markRunning();
$this->em->flush();
// ---------------------------------------------------------
// EXPORT TAGS (NDJSON)
// ---------------------------------------------------------
$export = $this->exporter->export();
if (
!isset($export['path']) ||
!\is_string($export['path']) ||
!\file_exists($export['path'])
) {
throw new \RuntimeException('Export failed: NDJSON file missing.');
}
if (isset($export['count']) && (int)$export['count'] === 0) {
throw new \RuntimeException('Export produced zero tags.');
}
// ---------------------------------------------------------
// BUILD VECTOR INDEX
// ---------------------------------------------------------
$this->builder->build();
// ---------------------------------------------------------
// MARK COMPLETED
// ---------------------------------------------------------
$job->markCompleted();
$this->em->flush();
$output->writeln('<info>OK</info>');
$output->writeln('tags.ndjson: ' . $export['path']);
} catch (\Throwable $e) {
$output->writeln('<info>Tag rebuild successful.</info>');
$output->writeln('NDJSON: ' . $export['path']);
return Command::SUCCESS;
}
catch (\Throwable $e) {
$job->markFailed($e->getMessage());
$this->em->flush();
$output->writeln('<error>FAILED: ' . $e->getMessage() . '</error>');
@\flock($fh, LOCK_UN);
@\fclose($fh);
return Command::FAILURE;
}
finally {
@\flock($fh, LOCK_UN);
@\fclose($fh);
return Command::SUCCESS;
if ($fh) {
@\flock($fh, LOCK_UN);
@\fclose($fh);
}
}
}
}