feat: refresh existing snapshots from XML after sync

This commit is contained in:
Björn Fromme
2026-03-24 11:13:11 +01:00
parent 909e8a1d8e
commit 3b6ee90a7e
9 changed files with 289 additions and 22 deletions
+50
View File
@@ -179,6 +179,56 @@ class TravelDataService
return $travel;
}
/**
* Syncs existing snapshots from fresh XML for all entries in the given file map.
*
* Iterates every date/hotel combination, calls getTravelDataFromXml() which
* loads, enriches, and upserts the snapshot (hash-guarded; no write if unchanged).
*
* @param array<int|string, array{hotels: array<int|string, mixed>}> $xmlFileMap
*
* @return array{processed:int,failed:int}
*/
public function syncSnapshotsFromXml(array $xmlFileMap, ?callable $onProgress = null): array
{
$processed = 0;
$failed = 0;
foreach ($xmlFileMap as $dateId => $entry) {
foreach (array_keys($entry['hotels']) as $hotelId) {
try {
$travel = $this->getTravelDataFromXml((int) $dateId, $hotelId);
} catch (\Throwable $e) {
$this->logger->warning('Failed to sync snapshot from XML', [
'dateId' => $dateId,
'hotelId' => $hotelId,
'error' => $e->getMessage(),
]);
++$failed;
if (null !== $onProgress) {
($onProgress)();
}
continue;
}
if (null === $travel) {
++$failed;
if (null !== $onProgress) {
($onProgress)();
}
continue;
}
++$processed;
if (null !== $onProgress) {
($onProgress)();
}
}
}
return ['processed' => $processed, 'failed' => $failed];
}
/**
* Retrieve travel data specifically from remote API.
*
+8 -6
View File
@@ -176,9 +176,9 @@ class TravelSnapshotService
*
* @return array{processed:int,updated:int,failed:int}
*/
public function refreshExtendedSnapshots(int $limit = 500, bool $force = false, int $refreshAfterMinutes = 360, array $xmlAvailableDateIds = []): array
public function refreshExtendedSnapshots(int $limit = 500, bool $force = false, int $refreshAfterMinutes = 360, ?array $xmlAvailableDateIds = null): array
{
$dateToThreshold = new \DateTimeImmutable(sprintf('-%d days', $this->retentionBufferDays));
$dateToThreshold = new \DateTimeImmutable('today');
$refreshBefore = new \DateTimeImmutable(sprintf('-%d minutes', $refreshAfterMinutes));
$candidates = true === $force
@@ -192,10 +192,12 @@ class TravelSnapshotService
$extendedResponseByDateId = [];
foreach ($candidates as $snapshot) {
// Skip travels whose XML is still live; their snapshot is kept authoritative
// by the XML load path (getTravelDataFromXml → upsertFromTravel). An empty
// $xmlAvailableDateIds means the file map could not be loaded, so fall back
// to refreshing everything rather than skipping all candidates.
// null → file map unavailable; skip all candidates (conservative fallback)
// [] → no XML files exist; fall through and refresh everything
// [...] → skip travels whose XML is still live
if (null === $xmlAvailableDateIds) {
continue;
}
if ([] !== $xmlAvailableDateIds && in_array($snapshot->getDateId(), $xmlAvailableDateIds, true)) {
continue;
}