From 2f2a124a06cba627757158bb5367433aeffa957d Mon Sep 17 00:00:00 2001 From: Prem Palanisamy Date: Wed, 29 Apr 2026 16:39:36 +0100 Subject: [PATCH] revert: redis resource cluster support + _APP_CONNECTIONS_CACHE fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cloud production runs four separate single-master+replica Dragonfly deployments (cache, queue-dragonfly, queue-usage, pubsub-dragonfly), not sharded Redis Cluster topology — confirmed by deploy/cloud/values + environments/production/*.values.yaml (Dragonfly Operator with replicas=2 = 1 primary + 1 read replica), and by the dev DSN scheme 'redis://' (not 'redis-cluster://'). So a standard \Redis client suffices for the direct redis resource (timelimit, Lock). Cloud just needs to pass _APP_REDIS_HOST/PORT/USER/ PASS through to the appwrite container — handled in the cloud PR's docker-compose.yml change. This reverts the resource to its original pre-PR shape. The utopia-php/lock cluster-support PR (utopia-php/lock#1) stays open at upstream as a future-ready option if cloud ever moves to actual Redis Cluster mode. --- app/controllers/general.php | 2 +- app/controllers/shared/api.php | 2 +- app/init/resources.php | 21 ++++----------------- src/Appwrite/Locking/Lock.php | 7 +++---- 4 files changed, 9 insertions(+), 23 deletions(-) diff --git a/app/controllers/general.php b/app/controllers/general.php index 9381843b64..9eabe56eac 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -137,7 +137,7 @@ function router(Http $utopia, Database $dbForPlatform, callable $getProjectDB, S if (!$project->isEmpty() && $project->getId() !== 'console') { $accessedAt = $project->getAttribute('accessedAt', 0); if (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_PROJECT_ACCESS)) > $accessedAt) { - $lock->set('projects', $project->getId()); + $lock->set('projects', $project->getId(), 'accessedAt', DateTime::now()); } /** diff --git a/app/controllers/shared/api.php b/app/controllers/shared/api.php index 3c679ce6ec..f88dc5eb4b 100644 --- a/app/controllers/shared/api.php +++ b/app/controllers/shared/api.php @@ -392,7 +392,7 @@ Http::init() if ($project->getId() !== 'console') { $accessedAt = $project->getAttribute('accessedAt', 0); if (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_PROJECT_ACCESS)) > $accessedAt) { - $lock->set('projects', $project->getId()); + $lock->set('projects', $project->getId(), 'accessedAt', DateTime::now()); } } diff --git a/app/init/resources.php b/app/init/resources.php index aa82c19b75..29506bfc9c 100644 --- a/app/init/resources.php +++ b/app/init/resources.php @@ -193,25 +193,12 @@ $container->set('cache', function (Group $pools, Telemetry $telemetry) { }, ['pools', 'telemetry']); $container->set('redis', function () { - // Prefer _APP_CONNECTIONS_CACHE (URI form, used by cloud and the pool layer) - // so that direct \Redis consumers (timelimit, Lock) match the same backend - // as the cache pool. Fall back to _APP_REDIS_* for CE-style configs. - $cacheDsn = System::getEnv('_APP_CONNECTIONS_CACHE', ''); - if ($cacheDsn !== '') { - $first = explode(';', $cacheDsn)[0]; - $uri = explode('=', $first, 2)[1] ?? $first; - $dsn = new DSN($uri); - $host = $dsn->getHost(); - $port = (int) ($dsn->getPort() ?: 6379); - $pass = $dsn->getPassword() ?? ''; - } else { - $host = System::getEnv('_APP_REDIS_HOST', 'localhost'); - $port = (int) System::getEnv('_APP_REDIS_PORT', 6379); - $pass = System::getEnv('_APP_REDIS_PASS', ''); - } + $host = System::getEnv('_APP_REDIS_HOST', 'localhost'); + $port = System::getEnv('_APP_REDIS_PORT', 6379); + $pass = System::getEnv('_APP_REDIS_PASS', ''); $redis = new \Redis(); - @$redis->pconnect($host, $port); + @$redis->pconnect($host, (int) $port); if ($pass) { $redis->auth($pass); } diff --git a/src/Appwrite/Locking/Lock.php b/src/Appwrite/Locking/Lock.php index 77b278860b..e545254ef3 100644 --- a/src/Appwrite/Locking/Lock.php +++ b/src/Appwrite/Locking/Lock.php @@ -7,7 +7,6 @@ use Closure; use Throwable; use Utopia\Console; use Utopia\Database\Database; -use Utopia\Database\DateTime; use Utopia\Database\Document; use Utopia\Database\Validator\Authorization; use Utopia\Lock\Distributed as DistributedLock; @@ -51,15 +50,15 @@ final class Lock public function set( string $collection, string $id, - string $attribute = 'accessedAt', - ?string $value = null, + string $attribute, + string $value, ): void { $key = "lock:platform:{$this->projectInternalId}:{$collection}:{$id}:{$attribute}"; $this->execute($key, $collection, function () use ($collection, $id, $attribute, $value) { $this->authorization->skip(fn () => $this->dbForPlatform->updateDocument( $collection, $id, - new Document([$attribute => $value ?? DateTime::now()]) + new Document([$attribute => $value]) )); }); }