Skip to content

Commit ab974df

Browse files
taka-oyamahalnique
andauthored
fix: separate auth cache and session pool to prevent race condition (#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]>
1 parent 380b7f7 commit ab974df

File tree

3 files changed

+59
-10
lines changed

3 files changed

+59
-10
lines changed

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
# v6.1.0 (Not Released Yet)
1+
# v6.1.1 (Not Released Yet)
2+
3+
Fixed
4+
- Bug where auth and session pool writing to the same file may cause race condition (#152)
5+
6+
# v6.1.0 (2023-11-29)
27

38
Added
49
- Add support for [NUMERIC](https://cloud.google.com/spanner/docs/reference/standard-sql/data-types#numeric_type) column type. (#145)

phpstan.neon

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,6 @@ parameters:
3535
- message: '#^Property Colopl\\Spanner\\Session\\SessionInfo\:\:\$labels \(array\<string, string\>\) does not accept array\.$#'
3636
path: src/Session/SessionInfo.php
3737
count: 1
38+
- 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\\>\\.$#"
39+
count: 1
40+
path: src/SpannerServiceProvider.php

src/SpannerServiceProvider.php

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@
2121
use Colopl\Spanner\Console\SessionsCommand;
2222
use Colopl\Spanner\Console\WarmupCommand;
2323
use Google\Cloud\Spanner\Session\CacheSessionPool;
24+
use Google\Cloud\Spanner\Session\SessionPoolInterface;
2425
use Illuminate\Database\DatabaseManager;
2526
use Illuminate\Queue\QueueManager;
2627
use Illuminate\Support\Facades\DB;
2728
use Illuminate\Support\ServiceProvider;
29+
use LogicException;
2830
use Symfony\Component\Cache\Adapter\AdapterInterface;
2931
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
3032

@@ -56,40 +58,76 @@ public function boot(): void
5658
}
5759

5860
/**
59-
* @param array $config
61+
* @param array{
62+
* name: string,
63+
* instance: string,
64+
* database: string,
65+
* prefix: string,
66+
* cache_path: string|null,
67+
* session_pool: array<string, mixed>,
68+
* } $config
6069
* @return Connection
6170
*/
6271
protected function createSpannerConnection(array $config): Connection
6372
{
64-
$cache = $this->getCacheAdapter(
65-
$config['name'],
66-
$config['cache_path'] ?? null,
67-
);
68-
6973
return new Connection(
7074
$config['instance'],
7175
$config['database'],
7276
$config['prefix'],
7377
$config,
74-
$cache,
75-
new CacheSessionPool($cache, $config['session_pool'] ?? [])
78+
$this->createAuthCache($config),
79+
$this->createSessionPool($config),
7680
);
7781
}
7882

7983
/**
8084
* @param array<string, mixed> $config
8185
* @param string $name
82-
* @return array<string, mixed>
86+
* @return array{
87+
* name: string,
88+
* instance: string,
89+
* database: string,
90+
* prefix: string,
91+
* cache_path: string|null,
92+
* session_pool: array<string, mixed>,
93+
* } $config
8394
*/
8495
protected function parseConfig(array $config, string $name): array
8596
{
97+
if ($name === '_auth') {
98+
throw new LogicException('Connection name "_auth" is reserved.');
99+
}
100+
86101
return $config + [
87102
'prefix' => '',
88103
'name' => $name,
104+
'cache_path' => null,
105+
'session_pool' => [],
89106
'useGapicBackoffs' => true,
90107
];
91108
}
92109

110+
/**
111+
* @param array{ cache_path: string|null } $config
112+
* @return AdapterInterface
113+
*/
114+
protected function createAuthCache(array $config): AdapterInterface
115+
{
116+
return $this->getCacheAdapter('_auth', $config['cache_path']);
117+
}
118+
119+
/**
120+
* @param array{ name: string, cache_path: string|null, session_pool: array<string, mixed> } $config
121+
* @return SessionPoolInterface
122+
*/
123+
protected function createSessionPool(array $config): SessionPoolInterface
124+
{
125+
return new CacheSessionPool(
126+
$this->getCacheAdapter($config['name'], $config['cache_path']),
127+
$config['session_pool'],
128+
);
129+
}
130+
93131
/**
94132
* @param string $namespace
95133
* @param string|null $path
@@ -101,6 +139,9 @@ protected function getCacheAdapter(string $namespace, ?string $path): AdapterInt
101139
return new FilesystemAdapter($namespace, 0, $path);
102140
}
103141

142+
/**
143+
* @return void
144+
*/
104145
protected function closeSessionAfterEachQueueJob(): void
105146
{
106147
$this->app->resolving('queue', function (QueueManager $queue): void {

0 commit comments

Comments
 (0)