Skip to content

Commit 5fb59eb

Browse files
committed
wip
1 parent 21d8397 commit 5fb59eb

10 files changed

Lines changed: 138 additions & 171 deletions

File tree

system/Cache/CacheFactory.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,6 @@ public static function getHandler(Cache $config, ?string $handler = null, ?strin
8686
$adapter = self::getHandler($config, $backup, 'dummy');
8787
}
8888

89-
// Wrap with reconnect decorator for automatic reconnection on failure
90-
$adapter = new ReconnectCacheDecorator($adapter);
91-
9289
return $adapter;
9390
}
9491
}

system/Cache/Handlers/BaseHandler.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,26 @@ public function remember(string $key, int $ttl, Closure $callback): mixed
8787

8888
return $value;
8989
}
90+
91+
/**
92+
* Check if connection is alive.
93+
*
94+
* Default implementation for handlers that don't require connection management.
95+
* Handlers with persistent connections (Redis, Predis, Memcached) should override this.
96+
*/
97+
public function ping(): bool
98+
{
99+
return true;
100+
}
101+
102+
/**
103+
* Reconnect to the cache server.
104+
*
105+
* Default implementation for handlers that don't require connection management.
106+
* Handlers with persistent connections (Redis, Predis, Memcached) should override this.
107+
*/
108+
public function reconnect(): bool
109+
{
110+
return true;
111+
}
90112
}

system/Cache/Handlers/MemcachedHandler.php

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -219,23 +219,40 @@ public function isSupported(): bool
219219
return extension_loaded('memcached') || extension_loaded('memcache');
220220
}
221221

222-
/**
223-
* Reconnect to Memcached server
224-
*
225-
* Used by ReconnectCacheDecorator to restore connection after failure.
226-
*/
222+
public function ping(): bool
223+
{
224+
if (! isset($this->memcached)) {
225+
return false;
226+
}
227+
228+
$version = $this->memcached->getVersion();
229+
230+
if ($this->memcached instanceof Memcached) {
231+
// Memcached extension returns array with server:port => version
232+
if (! is_array($version)) {
233+
return false;
234+
}
235+
236+
$serverKey = $this->config['host'] . ':' . $this->config['port'];
237+
238+
return isset($version[$serverKey]) && $version[$serverKey] !== false;
239+
}
240+
241+
if ($this->memcached instanceof Memcache) {
242+
// Memcache extension returns string version
243+
return is_string($version) && $version !== false && $version !== '';
244+
}
245+
246+
return false;
247+
}
248+
227249
public function reconnect(): bool
228250
{
229-
// Close existing connection to avoid resource leak
230251
if (isset($this->memcached)) {
231-
try {
232-
if ($this->memcached instanceof Memcached) {
233-
$this->memcached->quit();
234-
} elseif ($this->memcached instanceof Memcache) {
235-
$this->memcached->close();
236-
}
237-
} catch (Exception $e) {
238-
// Connection already dead, that's fine
252+
if ($this->memcached instanceof Memcached) {
253+
$this->memcached->quit();
254+
} elseif ($this->memcached instanceof Memcache) {
255+
$this->memcached->close();
239256
}
240257
}
241258

system/Cache/Handlers/PredisHandler.php

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -205,14 +205,27 @@ public function isSupported(): bool
205205
return class_exists(Client::class);
206206
}
207207

208-
/**
209-
* Reconnect to Redis server via Predis
210-
*
211-
* Used by ReconnectCacheDecorator to restore connection after failure.
212-
*/
208+
public function ping(): bool
209+
{
210+
if (! isset($this->redis)) {
211+
return false;
212+
}
213+
214+
try {
215+
$result = $this->redis->ping();
216+
217+
if (is_object($result)) {
218+
return $result->getPayload() === 'PONG';
219+
}
220+
221+
return $result === 'PONG';
222+
} catch (Exception $e) {
223+
return false;
224+
}
225+
}
226+
213227
public function reconnect(): bool
214228
{
215-
// Disconnect existing connection to avoid resource leak
216229
if (isset($this->redis)) {
217230
try {
218231
$this->redis->disconnect();

system/Cache/Handlers/RedisHandler.php

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -220,14 +220,23 @@ public function isSupported(): bool
220220
return extension_loaded('redis');
221221
}
222222

223-
/**
224-
* Reconnect to Redis server
225-
*
226-
* Used by ReconnectCacheDecorator to restore connection after failure.
227-
*/
223+
public function ping(): bool
224+
{
225+
if (! isset($this->redis)) {
226+
return false;
227+
}
228+
229+
try {
230+
$result = $this->redis->ping();
231+
232+
return $result === true || $result === '+PONG' || $result === 'PONG';
233+
} catch (RedisException $e) {
234+
return false;
235+
}
236+
}
237+
228238
public function reconnect(): bool
229239
{
230-
// Close existing connection to avoid resource leak
231240
if (isset($this->redis)) {
232241
try {
233242
$this->redis->close();

system/Cache/ReconnectCacheDecorator.php

Lines changed: 0 additions & 141 deletions
This file was deleted.

system/Config/BaseService.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,8 +394,13 @@ public static function resetForWorkerMode(WorkerMode $config): void
394394

395395
foreach (static::$instances as $serviceName => $service) {
396396
if ($serviceName === 'cache') {
397-
// Only persist cache in keep-alive mode
398397
if ($config->cacheStrategy === 'keep-alive') {
398+
// Ping the connection and reconnect if needed
399+
if (! $service->ping()) {
400+
$service->reconnect();
401+
}
402+
403+
// Persist cache instance in keep-alive mode
399404
$persistentInstances[$serviceName] = $service;
400405
}
401406

tests/system/Cache/Handlers/MemcachedHandlerTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,4 +188,19 @@ public function testGetMetaDataMiss(): void
188188
{
189189
$this->assertNull($this->handler->getMetaData(self::$dummy));
190190
}
191+
192+
public function testPing(): void
193+
{
194+
$this->assertTrue($this->handler->ping());
195+
}
196+
197+
public function testReconnect(): void
198+
{
199+
$this->handler->save(self::$key1, 'value');
200+
$this->assertSame('value', $this->handler->get(self::$key1));
201+
202+
$this->assertTrue($this->handler->reconnect());
203+
204+
$this->assertSame('value', $this->handler->get(self::$key1));
205+
}
191206
}

tests/system/Cache/Handlers/PredisHandlerTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,4 +184,19 @@ public function testIsSupported(): void
184184
{
185185
$this->assertTrue($this->handler->isSupported());
186186
}
187+
188+
public function testPing(): void
189+
{
190+
$this->assertTrue($this->handler->ping());
191+
}
192+
193+
public function testReconnect(): void
194+
{
195+
$this->handler->save(self::$key1, 'value');
196+
$this->assertSame('value', $this->handler->get(self::$key1));
197+
198+
$this->assertTrue($this->handler->reconnect());
199+
200+
$this->assertSame('value', $this->handler->get(self::$key1));
201+
}
187202
}

tests/system/Cache/Handlers/RedisHandlerTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,4 +233,19 @@ public function testIsSupported(): void
233233
{
234234
$this->assertTrue($this->handler->isSupported());
235235
}
236+
237+
public function testPing(): void
238+
{
239+
$this->assertTrue($this->handler->ping());
240+
}
241+
242+
public function testReconnect(): void
243+
{
244+
$this->handler->save(self::$key1, 'value');
245+
$this->assertSame('value', $this->handler->get(self::$key1));
246+
247+
$this->assertTrue($this->handler->reconnect());
248+
249+
$this->assertSame('value', $this->handler->get(self::$key1));
250+
}
236251
}

0 commit comments

Comments
 (0)