harden code and ingester

This commit is contained in:
team 1
2026-02-12 14:31:29 +01:00
parent 5a52e07edc
commit 994f582f35
8 changed files with 77 additions and 496 deletions

View File

@@ -5,25 +5,27 @@ namespace App\Service;
use App\Entity\DocumentVersion;
use App\Entity\IngestJob;
use App\Entity\User;
use App\Ingest\IngestFlow;
use Doctrine\ORM\EntityManagerInterface;
class IngestOrchestrator
final class IngestOrchestrator
{
public function __construct(
private LockService $lockService,
private IngestJobService $jobService,
private EntityManagerInterface $em,
) {}
private readonly LockService $lockService,
private readonly IngestJobService $jobService,
private readonly EntityManagerInterface $em,
private readonly IngestFlow $ingestFlow,
) {
}
/**
* Startet Ingest für eine bestimmte DocumentVersion
* Startet Ingest für eine bestimmte DocumentVersion (1 Job pro Run).
*/
public function runForVersion(
DocumentVersion $version,
User $user,
bool $dryRun = false
): IngestJob {
if (!$this->lockService->acquire()) {
throw new \RuntimeException('Another ingest job is already running.');
}
@@ -31,10 +33,16 @@ class IngestOrchestrator
$job = null;
try {
// Governance: nur PENDING/FAILED erlauben
$status = $version->getIngestStatus();
if (!in_array($status, [
DocumentVersion::INGEST_PENDING,
DocumentVersion::INGEST_FAILED,
], true)) {
throw new \RuntimeException(sprintf('Ingest not allowed for status "%s".', $status));
}
// --------------------------------------
// Job anlegen
// --------------------------------------
// Job anlegen (einmal!)
$job = $this->jobService->startJob(
IngestJob::TYPE_DOCUMENT,
$user,
@@ -42,33 +50,25 @@ class IngestOrchestrator
$version->getId(),
);
// --------------------------------------
// Version Status RUNNING
// --------------------------------------
// Status → RUNNING
$version->setIngestStatus(DocumentVersion::INGEST_RUNNING);
$this->em->flush();
// --------------------------------------
// Simulierter Ablauf (noch kein echter Ingest)
// --------------------------------------
if ($dryRun) {
usleep(200000);
} else {
// Später:
// - KnowledgeIngestService
// - ChunkWriter
// - VectorIngestCommand
// Fachlogik ausführen (Flow erzeugt keine Jobs!)
$this->ingestFlow->ingestDocumentVersion($version, $job->getLogPath());
}
// --------------------------------------
// Erfolg
// --------------------------------------
$version->setIngestStatus(DocumentVersion::INGEST_INDEXED);
$this->jobService->markCompleted($job);
$this->em->flush();
} catch (\Throwable $e) {
return $job;
} catch (\Throwable $e) {
if ($job) {
$this->jobService->markFailed($job, $e->getMessage());
}
@@ -81,12 +81,10 @@ class IngestOrchestrator
} finally {
$this->lockService->release();
}
return $job;
}
/**
* Globaler Reindex
* Globaler Reindex aller aktiven Dokumente.
*/
public function runGlobal(User $user, bool $dryRun = false): IngestJob
{
@@ -97,24 +95,19 @@ class IngestOrchestrator
$job = null;
try {
$job = $this->jobService->startJob(
IngestJob::TYPE_GLOBAL_REINDEX,
$user
);
$job = $this->jobService->startJob(IngestJob::TYPE_GLOBAL_REINDEX, $user);
if ($dryRun) {
usleep(200000);
} else {
// Später:
// - Alle aktiven Dokumente neu ingestieren
// - Global vector rebuild
$this->ingestFlow->globalReindex($job->getLogPath());
}
$this->jobService->markCompleted($job);
} catch (\Throwable $e) {
return $job;
} catch (\Throwable $e) {
if ($job) {
$this->jobService->markFailed($job, $e->getMessage());
}
@@ -124,7 +117,5 @@ class IngestOrchestrator
} finally {
$this->lockService->release();
}
return $job;
}
}