diff --git a/CHANGELOG.md b/CHANGELOG.md index 5baee761..a2be3364 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# v4.5.0 (Not released yet) + +Added +- Command `spanner:warmup` now has a new option `--skip-on-error` which will skip any connections which throws an exception. + # v4.4.0 Added diff --git a/docker-compose.yml b/docker-compose.yml index a07201f6..0c6521d0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,4 +9,4 @@ services: depends_on: - emulator emulator: - image: gcr.io/cloud-spanner-emulator/emulator + image: gcr.io/cloud-spanner-emulator/emulator:1.4.9 diff --git a/src/Console/WarmupCommand.php b/src/Console/WarmupCommand.php index a5b19877..4daf99b8 100644 --- a/src/Console/WarmupCommand.php +++ b/src/Console/WarmupCommand.php @@ -18,16 +18,21 @@ namespace Colopl\Spanner\Console; use Colopl\Spanner\Connection as SpannerConnection; +use Google\Cloud\Core\Exception\ServiceException; use Illuminate\Console\Command; use Illuminate\Database\DatabaseManager; class WarmupCommand extends Command { protected $signature = 'spanner:warmup {connections?* : The database connections to be warmed up} - {--refresh : Will clear all existing sessions first.}'; + {--refresh : Will clear all existing sessions first.} + {--skip-on-error : Will skip the connection if error is thrown.}'; - protected $description = 'Warmup Spanner\'s Session Pool.'; + protected $description = "Warmup Spanner's Session Pool."; + /** + * @throws ServiceException + */ public function handle(DatabaseManager $db): void { $connectionNames = (array)$this->argument('connections'); @@ -41,10 +46,16 @@ public function handle(DatabaseManager $db): void ); $refresh = (bool)($this->option('refresh') ?? false); + $skipOnError = (bool)($this->option('skip-on-error') ?? false); foreach ($spannerConnectionNames as $name) { $connection = $db->connection($name); - if ($connection instanceof SpannerConnection) { + + if (!$connection instanceof SpannerConnection) { + continue; + } + + try { if ($refresh) { $this->info("Cleared all existing sessions for {$name}"); $connection->clearSessionPool(); @@ -52,6 +63,10 @@ public function handle(DatabaseManager $db): void $count = $connection->warmupSessionPool(); $this->info("Warmed up {$count} sessions for {$name}"); + } catch (ServiceException $e) { + $skipOnError + ? $this->warn("Skipping warmup for {$name} due to " . $e::class . ": {$e->getMessage()}") + : throw $e; } } } diff --git a/tests/Console/WarmupCommandTest.php b/tests/Console/WarmupCommandTest.php index 4ffdaf35..4bf3873c 100644 --- a/tests/Console/WarmupCommandTest.php +++ b/tests/Console/WarmupCommandTest.php @@ -18,6 +18,8 @@ namespace Colopl\Spanner\Tests\Console; use Colopl\Spanner\Connection; +use Google\Cloud\Core\Exception\NotFoundException; +use Illuminate\Support\Facades\DB; class WarmupCommandTest extends TestCase @@ -77,4 +79,42 @@ public function test_with_refresh(): void ->assertSuccessful() ->run(); } + + public function test_with_missing_instance(): void + { + $this->expectException(NotFoundException::class); + $this->expectExceptionMessageMatches('/Instance not found:/'); + + config()->set('database.connections.none', [ + 'driver' => 'spanner', + 'instance' => 'nil', + 'database' => 'nil', + ]); + + try { + $this->artisan('spanner:warmup', ['connections' => 'none']) + ->assertFailed() + ->run(); + } finally { + // prevents truncate from running on connection during teardown. + DB::purge('none'); + } + } + + public function test_with_skip_on_error(): void + { + config()->set('database.connections.none', [ + 'driver' => 'spanner', + 'instance' => 'nil', + 'database' => 'nil', + ]); + + $this->artisan('spanner:warmup', ['connections' => 'none', '--skip-on-error' => true]) + ->expectsOutputToContain('Skipping warmup for none') + ->assertSuccessful() + ->run(); + + // prevents truncate from running on connection during teardown. + DB::purge('none'); + } }