Fixed GeolocationDbUpdater so that it does not try to interact with the reader if the file does not exist, preventing later errors

This commit is contained in:
Alejandro Celaya 2019-07-23 17:07:40 +02:00
parent c6fdd8a59f
commit 999beef349
5 changed files with 27 additions and 11 deletions

View File

@ -14,7 +14,7 @@ $logger = $isSwoole ? [
],
'shlink_stdout_handler' => [
'class' => StreamHandler::class,
'level' => Logger::INFO,
'level' => Logger::DEBUG,
'stream' => 'php://stdout',
'formatter' => 'dashed',
],

View File

@ -5,11 +5,11 @@ namespace Shlinkio\Shlink\CLI\Util;
use Cake\Chronos\Chronos;
use GeoIp2\Database\Reader;
use InvalidArgumentException;
use Shlinkio\Shlink\CLI\Exception\GeolocationDbUpdateFailedException;
use Shlinkio\Shlink\Common\Exception\RuntimeException;
use Shlinkio\Shlink\Common\IpGeolocation\GeoLite2\DbUpdaterInterface;
use Symfony\Component\Lock\Factory as Locker;
use Throwable;
class GeolocationDbUpdater implements GeolocationDbUpdaterInterface
{
@ -32,24 +32,33 @@ class GeolocationDbUpdater implements GeolocationDbUpdaterInterface
/**
* @throws GeolocationDbUpdateFailedException
*/
public function checkDbUpdate(callable $mustBeUpdated = null, callable $handleProgress = null): void
public function checkDbUpdate(?callable $mustBeUpdated = null, ?callable $handleProgress = null): void
{
$lock = $this->locker->createLock(self::LOCK_NAME);
$lock->acquire(true); // Block until lock is released
try {
$meta = $this->geoLiteDbReader->metadata();
if ($this->buildIsTooOld($meta->__get('buildEpoch'))) {
$this->downloadNewDb(true, $mustBeUpdated, $handleProgress);
}
} catch (InvalidArgumentException $e) {
// This is the exception thrown by the reader when the database file does not exist
$this->downloadNewDb(false, $mustBeUpdated, $handleProgress);
$this->downloadIfNeeded($mustBeUpdated, $handleProgress);
} catch (Throwable $e) {
throw $e;
} finally {
$lock->release();
}
}
private function downloadIfNeeded(?callable $mustBeUpdated, ?callable $handleProgress): void
{
if (! $this->dbUpdater->databaseFileExists()) {
$this->downloadNewDb(false, $mustBeUpdated, $handleProgress);
return;
}
$meta = $this->geoLiteDbReader->metadata();
if ($this->buildIsTooOld($meta->__get('buildEpoch'))) {
$this->downloadNewDb(true, $mustBeUpdated, $handleProgress);
}
}
private function buildIsTooOld(int $buildTimestamp): bool
{
$buildDate = Chronos::createFromTimestamp($buildTimestamp);

View File

@ -10,5 +10,5 @@ interface GeolocationDbUpdaterInterface
/**
* @throws GeolocationDbUpdateFailedException
*/
public function checkDbUpdate(callable $mustBeUpdated = null, callable $handleProgress = null): void;
public function checkDbUpdate(?callable $mustBeUpdated = null, ?callable $handleProgress = null): void;
}

View File

@ -98,4 +98,9 @@ class DbUpdater implements DbUpdaterInterface
// Ignore any error produced when trying to delete temp files
}
}
public function databaseFileExists(): bool
{
return $this->filesystem->exists($this->options->getDbLocation());
}
}

View File

@ -7,6 +7,8 @@ use Shlinkio\Shlink\Common\Exception\RuntimeException;
interface DbUpdaterInterface
{
public function databaseFileExists(): bool;
/**
* @throws RuntimeException
*/