Skip to content

Commit 063c612

Browse files
committed
add redis+memcached test connection
1 parent fa8f3c6 commit 063c612

File tree

2 files changed

+81
-7
lines changed

2 files changed

+81
-7
lines changed

src/ApiCache.php

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Psr\Log\LoggerInterface;
99
use Symfony\Component\Cache\Adapter\AbstractAdapter;
1010
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
11+
use Symfony\Component\Cache\Adapter\MemcachedAdapter;
1112
use Symfony\Component\Cache\PruneableInterface;
1213

1314
/**
@@ -243,7 +244,7 @@ private function saveRemediations(array $decisions): bool
243244
}
244245
}
245246

246-
return $this->adapter->commit();
247+
return $this->commit();
247248
}
248249

249250
private function removeRemediations(array $decisions): bool
@@ -268,7 +269,7 @@ private function removeRemediations(array $decisions): bool
268269
}
269270
}
270271

271-
return $this->adapter->commit();
272+
return $this->commit();
272273
}
273274

274275
/**
@@ -291,17 +292,22 @@ private function saveRemediationsForIp(array $decisions, string $ip): string
291292
$remediation = $this->formatRemediationFromDecision(null);
292293
$remediationResult = $this->addRemediationToCacheItem($ip, $remediation[0], $remediation[1], $remediation[2]);
293294
}
294-
$this->adapter->commit();
295+
$this->commit();
295296

296297
return $remediationResult;
297298
}
298299

299300
public function clear(): bool
300301
{
301-
$cleared = $this->adapter->clear();
302+
$this->setCustomErrorHandler();
303+
try {
304+
$cleared = $this->adapter->clear();
305+
} finally {
306+
$this->unsetCustomErrorHandler();
307+
}
302308
$this->warmedUp = false;
303309
$this->defferUpdateCacheConfig(['warmed_up' => $this->warmedUp]);
304-
$this->adapter->commit();
310+
$this->commit();
305311
$this->logger->info('', ['type' => 'CACHE_CLEARED']);
306312

307313
return $cleared;
@@ -328,7 +334,7 @@ public function warmUp(): int
328334
if ($newDecisions) {
329335
$this->warmedUp = $this->saveRemediations($newDecisions);
330336
$this->defferUpdateCacheConfig(['warmed_up' => $this->warmedUp]);
331-
$this->adapter->commit();
337+
$this->commit();
332338
if (!$this->warmedUp) {
333339
throw new BouncerException('Unable to warm the cache up');
334340
}
@@ -338,7 +344,7 @@ public function warmUp(): int
338344
// Store the fact that the cache has been warmed up.
339345
$this->defferUpdateCacheConfig(['warmed_up' => true]);
340346

341-
$this->adapter->commit();
347+
$this->commit();
342348
$this->logger->info('', ['type' => 'CACHE_WARMED_UP', 'added_decisions' => $nbNew]);
343349

344350
return $nbNew;
@@ -447,6 +453,9 @@ public function get(string $ip): string
447453
return $remediation;
448454
}
449455

456+
/**
457+
* Prune the cache (only when using PHP File System cache).
458+
*/
450459
public function prune(): bool
451460
{
452461
if ($this->adapter instanceof PruneableInterface) {
@@ -458,4 +467,59 @@ public function prune(): bool
458467

459468
throw new BouncerException('Cache Adapter'.\get_class($this->adapter).' is not prunable.');
460469
}
470+
471+
/**
472+
* When Memcached connection fail, it throw an unhandled warning.
473+
* To catch this warning as a clean execption we have to temporarily change the error handler.
474+
*/
475+
private function setCustomErrorHandler(): void
476+
{
477+
if ($this->adapter instanceof MemcachedAdapter) {
478+
set_error_handler(function () {
479+
throw new BouncerException('Error when connecting to Memcached. Please fix the Memcached DSN or select another cache technology.');
480+
});
481+
}
482+
}
483+
484+
/**
485+
* When the selected cache adapter is MemcachedAdapter, revert to the previous error handler.
486+
* */
487+
private function unsetCustomErrorHandler(): void
488+
{
489+
if ($this->adapter instanceof MemcachedAdapter) {
490+
restore_error_handler();
491+
}
492+
}
493+
494+
/**
495+
* Wrap the cacheAdapter to catch warnings.
496+
*
497+
* @throws BouncerException if the connection was not successful
498+
* */
499+
private function commit(): bool
500+
{
501+
$this->setCustomErrorHandler();
502+
try {
503+
$result = $this->adapter->commit();
504+
} finally {
505+
$this->unsetCustomErrorHandler();
506+
}
507+
508+
return $result;
509+
}
510+
511+
/**
512+
* Test the connection to the cache system (Redis or Memcached).
513+
*
514+
* @throws BouncerException if the connection was not successful
515+
* */
516+
public function testConnection(): void
517+
{
518+
$this->setCustomErrorHandler();
519+
try {
520+
$this->adapter->getItem(' ');
521+
} finally {
522+
$this->unsetCustomErrorHandler();
523+
}
524+
}
461525
}

src/Bouncer.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,4 +196,14 @@ public function checkCaptcha(string $expected, string $try, string $ip)
196196

197197
return $solved;
198198
}
199+
200+
/**
201+
* Test the connection to the cache system (Redis or Memcached)
202+
*
203+
* @throws BouncerException if the connection was not successful
204+
* */
205+
public function testConnection()
206+
{
207+
return $this->apiCache->testConnection();
208+
}
199209
}

0 commit comments

Comments
 (0)