Skip to content

Commit

Permalink
fix: separate auth cache and session pool to prevent race condition (#…
Browse files Browse the repository at this point in the history
…152)

* fix: separate auth cache and session pool to prevent race condition

* update changelog

* fix stan error

* Update src/SpannerServiceProvider.php

Co-authored-by: halnique <[email protected]>

* type hint changed

* reserve auth name

* fix stan error

---------

Co-authored-by: halnique <[email protected]>
  • Loading branch information
taka-oyama and halnique authored Dec 11, 2023
1 parent 380b7f7 commit ab974df
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 10 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# v6.1.0 (Not Released Yet)
# v6.1.1 (Not Released Yet)

Fixed
- Bug where auth and session pool writing to the same file may cause race condition (#152)

# v6.1.0 (2023-11-29)

Added
- Add support for [NUMERIC](https://cloud.google.com/spanner/docs/reference/standard-sql/data-types#numeric_type) column type. (#145)
Expand Down
3 changes: 3 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ parameters:
- message: '#^Property Colopl\\Spanner\\Session\\SessionInfo\:\:\$labels \(array\<string, string\>\) does not accept array\.$#'
path: src/Session/SessionInfo.php
count: 1
- message: "#^Method Colopl\\\\Spanner\\\\SpannerServiceProvider\\:\\:parseConfig\\(\\) should return array\\{name\\: string, instance\\: string, database\\: string, prefix\\: string, cache_path\\: string|null, session_pool\\: array\\<string, mixed\\>\\} but returns non\\-empty\\-array\\<string, mixed\\>\\.$#"
count: 1
path: src/SpannerServiceProvider.php
59 changes: 50 additions & 9 deletions src/SpannerServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@
use Colopl\Spanner\Console\SessionsCommand;
use Colopl\Spanner\Console\WarmupCommand;
use Google\Cloud\Spanner\Session\CacheSessionPool;
use Google\Cloud\Spanner\Session\SessionPoolInterface;
use Illuminate\Database\DatabaseManager;
use Illuminate\Queue\QueueManager;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider;
use LogicException;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;

Expand Down Expand Up @@ -56,40 +58,76 @@ public function boot(): void
}

/**
* @param array $config
* @param array{
* name: string,
* instance: string,
* database: string,
* prefix: string,
* cache_path: string|null,
* session_pool: array<string, mixed>,
* } $config
* @return Connection
*/
protected function createSpannerConnection(array $config): Connection
{
$cache = $this->getCacheAdapter(
$config['name'],
$config['cache_path'] ?? null,
);

return new Connection(
$config['instance'],
$config['database'],
$config['prefix'],
$config,
$cache,
new CacheSessionPool($cache, $config['session_pool'] ?? [])
$this->createAuthCache($config),
$this->createSessionPool($config),
);
}

/**
* @param array<string, mixed> $config
* @param string $name
* @return array<string, mixed>
* @return array{
* name: string,
* instance: string,
* database: string,
* prefix: string,
* cache_path: string|null,
* session_pool: array<string, mixed>,
* } $config
*/
protected function parseConfig(array $config, string $name): array
{
if ($name === '_auth') {
throw new LogicException('Connection name "_auth" is reserved.');
}

return $config + [
'prefix' => '',
'name' => $name,
'cache_path' => null,
'session_pool' => [],
'useGapicBackoffs' => true,
];
}

/**
* @param array{ cache_path: string|null } $config
* @return AdapterInterface
*/
protected function createAuthCache(array $config): AdapterInterface
{
return $this->getCacheAdapter('_auth', $config['cache_path']);
}

/**
* @param array{ name: string, cache_path: string|null, session_pool: array<string, mixed> } $config
* @return SessionPoolInterface
*/
protected function createSessionPool(array $config): SessionPoolInterface
{
return new CacheSessionPool(
$this->getCacheAdapter($config['name'], $config['cache_path']),
$config['session_pool'],
);
}

/**
* @param string $namespace
* @param string|null $path
Expand All @@ -101,6 +139,9 @@ protected function getCacheAdapter(string $namespace, ?string $path): AdapterInt
return new FilesystemAdapter($namespace, 0, $path);
}

/**
* @return void
*/
protected function closeSessionAfterEachQueueJob(): void
{
$this->app->resolving('queue', function (QueueManager $queue): void {
Expand Down

0 comments on commit ab974df

Please sign in to comment.