Use separate cache circuit breakers per pool

This commit is contained in:
Chirag Aggarwal
2026-05-07 18:15:55 +05:30
parent 9242727811
commit ad37636952
4 changed files with 25 additions and 18 deletions
+5 -2
View File
@@ -74,10 +74,13 @@ $container->set('cache', function ($pools, Telemetry $telemetry) {
$adapters = [];
foreach ($list as $value) {
$adapters[] = new CachePool($pools->get($value));
$adapters[] = new CircuitBreakerCache(
new CachePool($pools->get($value)),
CircuitBreakerFactory::create($telemetry, "cache.{$value}")
);
}
return new Cache(new CircuitBreakerCache(new Sharding($adapters), CircuitBreakerFactory::create($telemetry)));
return new Cache(new Sharding($adapters));
}, ['pools', 'telemetry']);
$container->set('pools', function (Registry $register) {
+7 -7
View File
@@ -16,7 +16,6 @@ use Utopia\Abuse\Adapters\TimeLimit\Redis as TimeLimitRedis;
use Utopia\Cache\Adapter\Pool as CachePool;
use Utopia\Cache\Adapter\Sharding;
use Utopia\Cache\Cache;
use Utopia\CircuitBreaker\CircuitBreaker;
use Utopia\Config\Config;
use Utopia\Console;
use Utopia\Database\Adapter\Pool as DatabasePool;
@@ -187,21 +186,22 @@ $container->set('getLogsDB', function (Group $pools, Cache $cache, Authorization
$container->set('telemetry', fn () => new NoTelemetry());
$container->set('breakerForCache', fn (Telemetry $telemetry): CircuitBreaker => CircuitBreakerFactory::create($telemetry), ['telemetry']);
$container->set('cache', function (Group $pools, CircuitBreaker $breaker, Telemetry $telemetry) {
$container->set('cache', function (Group $pools, Telemetry $telemetry) {
$list = Config::getParam('pools-cache', []);
$adapters = [];
foreach ($list as $value) {
$adapters[] = new CachePool($pools->get($value));
$adapters[] = new CircuitBreakerCache(
new CachePool($pools->get($value)),
CircuitBreakerFactory::create($telemetry, "cache.{$value}")
);
}
$cache = new Cache(new CircuitBreakerCache(new Sharding($adapters), $breaker));
$cache = new Cache(new Sharding($adapters));
$cache->setTelemetry($telemetry);
return $cache;
}, ['pools', 'breakerForCache', 'telemetry']);
}, ['pools', 'telemetry']);
$container->set('redis', function () {
$host = System::getEnv('_APP_REDIS_HOST', 'localhost');
+11 -8
View File
@@ -177,23 +177,26 @@ if (!function_exists('getCache')) {
$list = Config::getParam('pools-cache', []);
$adapters = [];
foreach ($list as $value) {
$adapters[] = new CachePool($pools->get($value));
}
static $breakers = [];
static $telemetry = null;
static $telemetryResolved = false;
static $breaker = null;
if ($breaker === null) {
if (!$telemetryResolved) {
try {
$telemetry = $register->get('telemetry');
} catch (\Throwable) {
$telemetry = null;
}
$breaker = CircuitBreakerFactory::create($telemetry);
$telemetryResolved = true;
}
return $ctx['cache'] = new Cache(new CircuitBreakerCache(new Sharding($adapters), $breaker));
foreach ($list as $value) {
$breakers[$value] ??= CircuitBreakerFactory::create($telemetry, "cache.{$value}");
$adapters[] = new CircuitBreakerCache(new CachePool($pools->get($value)), $breakers[$value]);
}
return $ctx['cache'] = new Cache(new Sharding($adapters));
}
}
+2 -1
View File
@@ -11,12 +11,13 @@ class CircuitBreakerFactory
private const TIMEOUT = 30;
private const SUCCESS_THRESHOLD = 2;
public static function create(?Telemetry $telemetry = null): CircuitBreaker
public static function create(?Telemetry $telemetry = null, string $cacheKey = 'cache'): CircuitBreaker
{
return new CircuitBreaker(
threshold: self::THRESHOLD,
timeout: self::TIMEOUT,
successThreshold: self::SUCCESS_THRESHOLD,
cacheKey: $cacheKey,
telemetry: $telemetry,
);
}