Handle differently when trying to update geolocation and already in progress

This commit is contained in:
Alejandro Celaya 2024-12-15 12:03:01 +01:00
parent 853c50a819
commit 72a962ec6d
4 changed files with 19 additions and 1 deletions

View File

@ -56,6 +56,11 @@ class DownloadGeoLiteDbCommand extends Command implements GeolocationDownloadPro
return ExitCode::EXIT_WARNING; return ExitCode::EXIT_WARNING;
} }
if ($result === GeolocationResult::UPDATE_IN_PROGRESS) {
$this->io->warning('A geolocation db is already being downloaded by another process.');
return ExitCode::EXIT_WARNING;
}
if ($this->progressBar === null) { if ($this->progressBar === null) {
$this->io->info('GeoLite2 db file is up to date.'); $this->io->info('GeoLite2 db file is up to date.');
} else { } else {

View File

@ -77,6 +77,7 @@ class DownloadGeoLiteDbCommandTest extends TestCase
#[Test] #[Test]
#[TestWith([GeolocationResult::LICENSE_MISSING, 'It was not possible to download GeoLite2 db'])] #[TestWith([GeolocationResult::LICENSE_MISSING, 'It was not possible to download GeoLite2 db'])]
#[TestWith([GeolocationResult::MAX_ERRORS_REACHED, 'Max consecutive errors reached'])] #[TestWith([GeolocationResult::MAX_ERRORS_REACHED, 'Max consecutive errors reached'])]
#[TestWith([GeolocationResult::UPDATE_IN_PROGRESS, 'A geolocation db is already being downloaded'])]
public function warningIsPrintedForSomeResults(GeolocationResult $result, string $expectedWarningMessage): void public function warningIsPrintedForSomeResults(GeolocationResult $result, string $expectedWarningMessage): void
{ {
$this->dbUpdater->expects($this->once())->method('checkDbUpdate')->withAnyParameters()->willReturn($result); $this->dbUpdater->expects($this->once())->method('checkDbUpdate')->withAnyParameters()->willReturn($result);

View File

@ -12,6 +12,7 @@ use Shlinkio\Shlink\IpGeolocation\Exception\DbUpdateException;
use Shlinkio\Shlink\IpGeolocation\Exception\MissingLicenseException; use Shlinkio\Shlink\IpGeolocation\Exception\MissingLicenseException;
use Shlinkio\Shlink\IpGeolocation\GeoLite2\DbUpdaterInterface; use Shlinkio\Shlink\IpGeolocation\GeoLite2\DbUpdaterInterface;
use Symfony\Component\Lock\LockFactory; use Symfony\Component\Lock\LockFactory;
use Throwable;
use function sprintf; use function sprintf;
@ -65,7 +66,7 @@ readonly class GeolocationDbUpdater implements GeolocationDbUpdaterInterface
// If most recent attempt is in progress, skip check. // If most recent attempt is in progress, skip check.
// This is a safety check in case the lock is released before the previous download has finished. // This is a safety check in case the lock is released before the previous download has finished.
if ($mostRecentDownload?->isInProgress()) { if ($mostRecentDownload?->isInProgress()) {
return GeolocationResult::CHECK_SKIPPED; return GeolocationResult::UPDATE_IN_PROGRESS;
} }
$amountOfErrorsSinceLastSuccess = 0; $amountOfErrorsSinceLastSuccess = 0;
@ -122,6 +123,9 @@ readonly class GeolocationDbUpdater implements GeolocationDbUpdaterInterface
sprintf('%s Prev: %s', $e->getMessage(), $e->getPrevious()?->getMessage() ?? '-'), sprintf('%s Prev: %s', $e->getMessage(), $e->getPrevious()?->getMessage() ?? '-'),
); );
throw $e; throw $e;
} catch (Throwable $e) {
$dbUpdate->finishWithError(sprintf('Unknown error: %s', $e->getMessage()));
throw $e;
} finally { } finally {
$this->em->flush(); $this->em->flush();
} }

View File

@ -4,10 +4,18 @@ namespace Shlinkio\Shlink\Core\Geolocation;
enum GeolocationResult enum GeolocationResult
{ {
/** Geolocation is not relevant, so updates are skipped */
case CHECK_SKIPPED; case CHECK_SKIPPED;
/** Update is skipped because max amount of consecutive errors was reached */
case MAX_ERRORS_REACHED; case MAX_ERRORS_REACHED;
/** Update was skipped because a geolocation license key was not provided */
case LICENSE_MISSING; case LICENSE_MISSING;
/** A geolocation database didn't exist and has been created */
case DB_CREATED; case DB_CREATED;
/** An outdated geolocation database existed and has been updated */
case DB_UPDATED; case DB_UPDATED;
/** Geolocation database does not need to be updated yet */
case DB_IS_UP_TO_DATE; case DB_IS_UP_TO_DATE;
/** Geolocation db update is currently in progress */
case UPDATE_IN_PROGRESS;
} }