phase a audit
This commit is contained in:
@@ -15,15 +15,13 @@ final class IndexMetaManager
|
||||
string $runTimePath,
|
||||
IndexConfigurationProvider $provider
|
||||
) {
|
||||
$this->metaPath = $metaPath;
|
||||
$this->provider = $provider;
|
||||
|
||||
// runtime liegt im selben Verzeichnis
|
||||
$this->metaPath = $metaPath;
|
||||
$this->runtimePath = $runTimePath;
|
||||
$this->provider = $provider;
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// META (Governance – unverändert lassen!)
|
||||
// META (Governance – unverändert inhaltlich)
|
||||
// =====================================================
|
||||
|
||||
public function ensureExists(): void
|
||||
@@ -39,10 +37,12 @@ final class IndexMetaManager
|
||||
return null;
|
||||
}
|
||||
|
||||
return json_decode(
|
||||
$data = json_decode(
|
||||
(string) file_get_contents($this->metaPath),
|
||||
true
|
||||
);
|
||||
|
||||
return is_array($data) ? $data : null;
|
||||
}
|
||||
|
||||
public function validateAgainstCurrent(): void
|
||||
@@ -85,18 +85,7 @@ final class IndexMetaManager
|
||||
$config->toStructureArray()
|
||||
);
|
||||
|
||||
$dir = dirname($this->metaPath);
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0777, true);
|
||||
}
|
||||
|
||||
file_put_contents(
|
||||
$this->metaPath,
|
||||
json_encode(
|
||||
$payload,
|
||||
JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
|
||||
)
|
||||
);
|
||||
$this->atomicWriteJson($this->metaPath, $payload);
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
@@ -109,20 +98,12 @@ final class IndexMetaManager
|
||||
return;
|
||||
}
|
||||
|
||||
$dir = dirname($this->runtimePath);
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0777, true);
|
||||
}
|
||||
|
||||
$payload = [
|
||||
'chunk_count' => 0,
|
||||
'chunk_count' => 0,
|
||||
'last_rebuild_at' => null,
|
||||
];
|
||||
|
||||
file_put_contents(
|
||||
$this->runtimePath,
|
||||
json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)
|
||||
);
|
||||
$this->atomicWriteJson($this->runtimePath, $payload);
|
||||
}
|
||||
|
||||
public function updateRuntimeStats(int $chunkCount): void
|
||||
@@ -130,14 +111,11 @@ final class IndexMetaManager
|
||||
$this->ensureRuntimeFileExists();
|
||||
|
||||
$payload = [
|
||||
'chunk_count' => $chunkCount,
|
||||
'chunk_count' => $chunkCount,
|
||||
'last_rebuild_at' => (new \DateTimeImmutable())->format(DATE_ATOM),
|
||||
];
|
||||
|
||||
file_put_contents(
|
||||
$this->runtimePath,
|
||||
json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)
|
||||
);
|
||||
$this->atomicWriteJson($this->runtimePath, $payload);
|
||||
}
|
||||
|
||||
public function getRuntimeChunkCount(): int
|
||||
@@ -151,5 +129,37 @@ final class IndexMetaManager
|
||||
|
||||
return (int)($data['chunk_count'] ?? 0);
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// INTERNAL ATOMIC JSON WRITE
|
||||
// =====================================================
|
||||
|
||||
private function atomicWriteJson(string $path, array $payload): void
|
||||
{
|
||||
$dir = dirname($path);
|
||||
|
||||
if (!is_dir($dir) && !mkdir($dir, 0777, true) && !is_dir($dir)) {
|
||||
throw new \RuntimeException('Unable to create directory for meta/runtime');
|
||||
}
|
||||
|
||||
$tmpPath = $path . '.tmp';
|
||||
|
||||
$json = json_encode(
|
||||
$payload,
|
||||
JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
|
||||
);
|
||||
|
||||
if ($json === false) {
|
||||
throw new \RuntimeException('Unable to encode JSON payload');
|
||||
}
|
||||
|
||||
if (file_put_contents($tmpPath, $json) === false) {
|
||||
throw new \RuntimeException('Unable to write temporary JSON file');
|
||||
}
|
||||
|
||||
if (!rename($tmpPath, $path)) {
|
||||
@unlink($tmpPath);
|
||||
throw new \RuntimeException('Atomic switch failed for JSON file');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user