From c6a054f88de2ab6c40c29659ef2d9847c29c5cdf Mon Sep 17 00:00:00 2001 From: shimon Date: Thu, 6 Oct 2022 15:33:57 +0300 Subject: [PATCH] redis-syncs --- app/config/services.php | 13 +++++++++++ app/controllers/api/syncs.php | 44 +++++++++++++++++++++++++++++++++++ app/workers/syncsIn.php | 20 ++++++++++++++++ app/workers/syncsOut.php | 42 +++++++++++++++++++++++++++++++-- 4 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 app/controllers/api/syncs.php diff --git a/app/config/services.php b/app/config/services.php index 7369574a80..a1af27aa6e 100644 --- a/app/config/services.php +++ b/app/config/services.php @@ -186,4 +186,17 @@ return [ 'optional' => false, 'icon' => '', ], + 'syncs' => [ + 'key' => 'syncs', + 'name' => 'syncs', + 'subtitle' => 'Appwrite\'s cloud regions syncs Endpoint', + 'description' => 'Syncs Endpoint', + 'controller' => 'api/syncs.php', + 'sdk' => false, + 'docs' => false, + 'docsUrl' => '', + 'tests' => true, + 'optional' => false, + 'icon' => '', + ], ]; diff --git a/app/controllers/api/syncs.php b/app/controllers/api/syncs.php new file mode 100644 index 0000000000..850f07600f --- /dev/null +++ b/app/controllers/api/syncs.php @@ -0,0 +1,44 @@ +desc('Purge cache keys') + ->label('scope', 'public') + ->param('keys', '', new ArrayList(new Text(100), 1000), 'Cache keys') + ->inject('request') + ->inject('response') + ->action(function (array $keys, Request $request, Response $response) { + + if (empty($keys)) { + throw new Exception(Exception::KEY_NOT_FOUND); + } + + $token = $request->getHeader('authorization'); + $token = str_replace(["Bearer"," "], "", $token); + $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 900, 10); +// try { +// $payload = $jwt->decode($token); +// } catch (JWTException $error) { +// throw new Exception(Exception::USER_JWT_INVALID, 'Failed to verify JWT. ' . $error->getMessage()); +// } + + $syncIn = new SyncIn(); + foreach ($keys as $key) { + $syncIn + ->addKey($key) + ->trigger(); + } + + $response + ->setStatusCode(Response::STATUS_CODE_OK) + ->send(); + }); diff --git a/app/workers/syncsIn.php b/app/workers/syncsIn.php index 8fef867c14..d70e9cafca 100644 --- a/app/workers/syncsIn.php +++ b/app/workers/syncsIn.php @@ -1,6 +1,8 @@ args['key'])) { + //var_dump('Purging -> ' . $this->args['key'] . ' from Redis cache'); + $this->getCache()->purge($this->args['key']); + } } + /** + * Get cache + * @return RedisCache + * @throws Exception + */ + private function getCache(): RedisCache + { + global $register; + + return new RedisCache($register->get('cache')); + } + + + public function shutdown(): void { } diff --git a/app/workers/syncsOut.php b/app/workers/syncsOut.php index d9e9260af2..af596e46d4 100644 --- a/app/workers/syncsOut.php +++ b/app/workers/syncsOut.php @@ -1,6 +1,8 @@ '172.17.0.1', + 'nyc1' => '172.17.0.1', + 'blr1' => '172.17.0.1', + ]; + public function getName(): string { return "syncs-out"; @@ -23,8 +31,38 @@ class SyncsOutV1 extends Worker public function run(): void { - var_dump('run'); - var_dump($this->args['key']); + //TODO current region env implementation + $currentRegion = 'nyc1'; + + $data['keys'][] = $this->args['key']; + $jwt = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 900, 10); + $token = $jwt->encode($data); + + foreach ($this->regions as $region => $host) { + if ($currentRegion === $region) { + continue; + } + $ch = curl_init($host . '/v1/syncs'); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Authorization: Bearer ' . $token, + 'Content-Type: application/json' + ]); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 5); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); + curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); + + for ($attempts = 0; $attempts < 6; $attempts++) { + curl_exec($ch); + $responseStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE); + if ($responseStatus === 200) { + break; + } + + sleep(2); + } + curl_close($ch); + } }