From ceb670e09040f811a20668110bced7086b7e7a1a Mon Sep 17 00:00:00 2001 From: Matej Baco Date: Fri, 24 Mar 2023 07:51:55 +0000 Subject: [PATCH 1/8] Add addressing method header --- app/http.php | 230 +++++++++++++++++++++++++++++--------------------- composer.json | 2 +- composer.lock | 198 +++++++++++++++++++++---------------------- 3 files changed, 231 insertions(+), 199 deletions(-) diff --git a/app/http.php b/app/http.php index f459831..94f75d7 100644 --- a/app/http.php +++ b/app/http.php @@ -86,44 +86,51 @@ App::setResource('balancer', function (Algorithm $algorithm, Request $request) { global $state; $runtimeId = $request->getHeader('x-opr-runtime-id', ''); + $method = $request->getHeader('x-opr-addressing-method', 'anycast-efficient'); $group = new Group(); + if ($method === 'anycast-fast') { + $algorithm = new Random(); + } + // Cold-started-only options $balancer1 = new Balancer($algorithm); // Only online executors $balancer1->addFilter(fn ($option) => $option->getState('status', 'offline') === 'online'); - // Only low host-cpu usage - $balancer1->addFilter(function ($option) { - /** - * @var array $state - */ - $state = \json_decode($option->getState('state', '{}'), true); - return ($state['usage'] ?? 100) < 80; - }); - - // Only low runtime-cpu usage - if (!empty($runtimeId)) { - $balancer1->addFilter(function ($option) use ($runtimeId) { + if ($method === 'anycast-efficient') { + // Only low host-cpu usage + $balancer1->addFilter(function ($option) { /** * @var array $state */ $state = \json_decode($option->getState('state', '{}'), true); - - /** - * @var array $runtimes - */ - $runtimes = $state['runtimes']; - - /** - * @var array $runtime - */ - $runtime = $runtimes[$runtimeId] ?? []; - - return ($runtime['usage'] ?? 100) < 80; + return ($state['usage'] ?? 100) < 80; }); + + // Only low runtime-cpu usage + if (!empty($runtimeId)) { + $balancer1->addFilter(function ($option) use ($runtimeId) { + /** + * @var array $state + */ + $state = \json_decode($option->getState('state', '{}'), true); + + /** + * @var array $runtimes + */ + $runtimes = $state['runtimes']; + + /** + * @var array $runtime + */ + $runtime = $runtimes[$runtimeId] ?? []; + + return ($runtime['usage'] ?? 100) < 80; + }); + } } // Any options @@ -242,109 +249,138 @@ function logError(Throwable $error, string $action, ?Logger $logger, Utopia\Rout ->inject('request') ->inject('response') ->action(function (Group $balancer, Request $request, Response $response) { - global $state; - $option = $balancer->run(); + $method = $request->getHeader('x-opr-addressing-method', 'anycast-efficient'); - if (!isset($option)) { - throw new Exception('No online executor found', 404); - } + $proxyRequest = function (string $hostname) use ($request) { + if (App::isDevelopment()) { + Console::info("Executing on " . $hostname); + } - /** - * @var string $hostname - */ - $hostname = $option->getState('hostname') ?? ''; + // Optimistic update. Mark runtime up instantly to prevent race conditions + // Next health check with confirm it started well, and update usage stats + $runtimeId = $request->getHeader('x-opr-runtime-id', ''); + if (!empty($runtimeId)) { + global $state; + $record = $state->get($hostname); - if (App::isDevelopment()) { - Console::info("Executing on " . $hostname); - } + $stateItem = \json_decode($record['state'] ?? '{}', true); - // Optimistic update. Mark runtime up instantly to prevent race conditions - // Next health check with confirm it started well, and update usage stats - $runtimeId = $request->getHeader('x-opr-runtime-id', ''); - if (!empty($runtimeId)) { - $record = $state->get($hostname); + if (!isset($stateItem['runtimes'])) { + $stateItem['runtimes'] = []; + } + + if (!isset($stateItem['runtimes'][$runtimeId])) { + $stateItem['runtimes'][$runtimeId] = []; + } + + $stateItem['runtimes'][$runtimeId]['status'] = 'pass'; + $stateItem['runtimes'][$runtimeId]['usage'] = 0; - $stateItem = \json_decode($record['state'] ?? '{}', true); + $record['state'] = \json_encode($stateItem); - if (!isset($stateItem['runtimes'])) { - $stateItem['runtimes'] = []; + $state->set($hostname, $record); } - if (!isset($stateItem['runtimes'][$runtimeId])) { - $stateItem['runtimes'][$runtimeId] = []; + $headers = \array_merge($request->getHeaders(), [ + 'authorization' => 'Bearer ' . App::getEnv('OPR_PROXY_EXECUTOR_SECRET', '') + ]); + + // Header used for testing + if (App::isDevelopment()) { + $headers = \array_merge($headers, [ + 'x-opr-executor-hostname' => $hostname + ]); } - $stateItem['runtimes'][$runtimeId]['status'] = 'pass'; - $stateItem['runtimes'][$runtimeId]['usage'] = 0; + $body = $request->getRawPayload(); - $record['state'] = \json_encode($stateItem); + $ch = \curl_init(); - $state->set($hostname, $record); - } + \curl_setopt($ch, CURLOPT_URL, $hostname . $request->getURI()); + \curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request->getMethod()); + \curl_setopt($ch, CURLOPT_POSTFIELDS, $body); + \curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + \curl_setopt($ch, CURLOPT_HEADER, true); + \curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); - $headers = \array_merge($request->getHeaders(), [ - 'authorization' => 'Bearer ' . App::getEnv('OPR_PROXY_EXECUTOR_SECRET', '') - ]); + $curlHeaders = []; + foreach ($headers as $header => $value) { + $curlHeaders[] = "{$header}: {$value}"; + } - // Header used for testing - if (App::isDevelopment()) { - $headers = \array_merge($headers, [ - 'x-opr-executor-hostname' => $hostname - ]); - } + \curl_setopt($ch, CURLOPT_HTTPHEADER, $curlHeaders); - $body = $request->getRawPayload(); + $executorResponse = \curl_exec($ch); - $ch = \curl_init(); + $statusCode = \curl_getinfo($ch, CURLINFO_HTTP_CODE); - \curl_setopt($ch, CURLOPT_URL, $hostname . $request->getURI()); - \curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request->getMethod()); - \curl_setopt($ch, CURLOPT_POSTFIELDS, $body); - \curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - \curl_setopt($ch, CURLOPT_HEADER, true); - \curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); + $error = \curl_error($ch); - $curlHeaders = []; - foreach ($headers as $header => $value) { - $curlHeaders[] = "{$header}: {$value}"; - } + $errNo = \curl_errno($ch); + + $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); + $headers = substr(\strval($executorResponse), 0, $header_size); + $body = substr(\strval($executorResponse), $header_size); - \curl_setopt($ch, CURLOPT_HTTPHEADER, $curlHeaders); + \curl_close($ch); - $executorResponse = \curl_exec($ch); + if ($errNo !== 0) { + throw new Exception('Unexpected curl error between proxy and executor: ' . $error); + } + + $headersArr = []; + if (!empty($headers)) { + $headers = preg_split("/\r\n|\n|\r/", $headers); + if ($headers) { + foreach ($headers as $header) { + if (\str_contains($header, ':')) { + [ $key, $value ] = \explode(':', $header, 2); + $headersArr[$key] = $value; + } + } + } + } - $statusCode = \curl_getinfo($ch, CURLINFO_HTTP_CODE); + return [ + 'statusCode' => $statusCode, + 'body' => $body, + 'headers' => $headersArr + ]; + }; - $error = \curl_error($ch); + if ($method === 'broadcast') { + foreach ($balancer->getOptions() as $option) { + /** + * @var string $hostname + */ + $hostname = $option->getState('hostname') ?? ''; - $errNo = \curl_errno($ch); + $proxyRequest($hostname); + } - $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); - $headers = substr(\strval($executorResponse), 0, $header_size); - $body = substr(\strval($executorResponse), $header_size); + $response->noContent(); + } else { + $option = $balancer->run(); - \curl_close($ch); + if (!isset($option)) { + throw new Exception('No online executor found', 404); + } - if ($errNo !== 0) { - throw new Exception('Unexpected curl error between proxy and executor: ' . $error); - } + /** + * @var string $hostname + */ + $hostname = $option->getState('hostname') ?? ''; - if (!empty($headers)) { - $headers = preg_split("/\r\n|\n|\r/", $headers); - if ($headers) { - foreach ($headers as $header) { - if (\str_contains($header, ':')) { - [ $key, $value ] = \explode(':', $header, 2); + $result = $proxyRequest($hostname); - $response->addHeader($key, $value); - } - } + foreach ($result['headers'] as $key => $value) { + $response->addHeader($key, $value); } - } - $response - ->setStatusCode($statusCode) - ->send($body); + $response + ->setStatusCode($result['statusCode']) + ->send($result['body']); + } }); App::error() diff --git a/composer.json b/composer.json index ec05ac5..3cd5ec5 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,7 @@ "utopia-php/registry": "0.6.*", "utopia-php/cli": "0.13.*", "utopia-php/logger": "0.3.*", - "utopia-php/balancer": "0.3.*" + "utopia-php/balancer": "dev-feat-get-options as 0.3.99" }, "require-dev": { "swoole/ide-helper": "4.8.5", diff --git a/composer.lock b/composer.lock index 1c3dca0..6206118 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6eee5ce073315a130f68743e00c95320", + "content-hash": "74f859d1d9486d08095871b97196d376", "packages": [ { "name": "utopia-php/balancer", - "version": "0.3.2", + "version": "dev-feat-get-options", "source": { "type": "git", "url": "https://github.com/utopia-php/balancer.git", - "reference": "8b14583a4d7d06ca8c3bd9aad6ba46b01d2f4b2e" + "reference": "42a61096c8f9ec81fd908d84618c73ef1914a021" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/balancer/zipball/8b14583a4d7d06ca8c3bd9aad6ba46b01d2f4b2e", - "reference": "8b14583a4d7d06ca8c3bd9aad6ba46b01d2f4b2e", + "url": "https://api.github.com/repos/utopia-php/balancer/zipball/42a61096c8f9ec81fd908d84618c73ef1914a021", + "reference": "42a61096c8f9ec81fd908d84618c73ef1914a021", "shasum": "" }, "require": { @@ -49,9 +49,9 @@ ], "support": { "issues": "https://github.com/utopia-php/balancer/issues", - "source": "https://github.com/utopia-php/balancer/tree/0.3.2" + "source": "https://github.com/utopia-php/balancer/tree/feat-get-options" }, - "time": "2022-11-08T16:48:37+00:00" + "time": "2023-03-16T12:17:42+00:00" }, { "name": "utopia-php/cli", @@ -152,22 +152,23 @@ }, { "name": "utopia-php/logger", - "version": "0.3.0", + "version": "0.3.1", "source": { "type": "git", "url": "https://github.com/utopia-php/logger.git", - "reference": "079656cb5169ca9600861eda0b6819199e3d4a57" + "reference": "de623f1ec1c672c795d113dd25c5bf212f7ef4fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/logger/zipball/079656cb5169ca9600861eda0b6819199e3d4a57", - "reference": "079656cb5169ca9600861eda0b6819199e3d4a57", + "url": "https://api.github.com/repos/utopia-php/logger/zipball/de623f1ec1c672c795d113dd25c5bf212f7ef4fc", + "reference": "de623f1ec1c672c795d113dd25c5bf212f7ef4fc", "shasum": "" }, "require": { "php": ">=8.0" }, "require-dev": { + "phpstan/phpstan": "1.9.x-dev", "phpunit/phpunit": "^9.3", "vimeo/psalm": "4.0.1" }, @@ -181,20 +182,6 @@ "license": [ "MIT" ], - "authors": [ - { - "name": "Eldad Fux", - "email": "eldad@appwrite.io" - }, - { - "name": "Matej Bačo", - "email": "matej@appwrite.io" - }, - { - "name": "Christy Jacob", - "email": "christy@appwrite.io" - } - ], "description": "Utopia Logger library is simple and lite library for logging information, such as errors or warnings. This library is aiming to be as simple and easy to learn and use.", "keywords": [ "appsignal", @@ -212,9 +199,9 @@ ], "support": { "issues": "https://github.com/utopia-php/logger/issues", - "source": "https://github.com/utopia-php/logger/tree/0.3.0" + "source": "https://github.com/utopia-php/logger/tree/0.3.1" }, - "time": "2022-03-18T10:56:57+00:00" + "time": "2023-02-10T15:52:50+00:00" }, { "name": "utopia-php/registry", @@ -323,30 +310,30 @@ "packages-dev": [ { "name": "doctrine/instantiator", - "version": "1.4.1", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^8.1" }, "require-dev": { - "doctrine/coding-standard": "^9", + "doctrine/coding-standard": "^11", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.16 || ^1", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" + "phpbench/phpbench": "^1.2", + "phpstan/phpstan": "^1.9.4", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5.27", + "vimeo/psalm": "^5.4" }, "type": "library", "autoload": { @@ -373,7 +360,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.1" + "source": "https://github.com/doctrine/instantiator/tree/2.0.0" }, "funding": [ { @@ -389,20 +376,20 @@ "type": "tidelift" } ], - "time": "2022-03-03T08:28:38+00:00" + "time": "2022-12-30T00:23:10+00:00" }, { "name": "laravel/pint", - "version": "v1.2.0", + "version": "v1.2.1", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "1d276e4c803397a26cc337df908f55c2a4e90d86" + "reference": "e60e2112ee779ce60f253695b273d1646a17d6f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/1d276e4c803397a26cc337df908f55c2a4e90d86", - "reference": "1d276e4c803397a26cc337df908f55c2a4e90d86", + "url": "https://api.github.com/repos/laravel/pint/zipball/e60e2112ee779ce60f253695b273d1646a17d6f1", + "reference": "e60e2112ee779ce60f253695b273d1646a17d6f1", "shasum": "" }, "require": { @@ -414,10 +401,10 @@ }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.11.0", - "illuminate/view": "^9.27", - "laravel-zero/framework": "^9.1.3", - "mockery/mockery": "^1.5.0", - "nunomaduro/larastan": "^2.2", + "illuminate/view": "^9.32.0", + "laravel-zero/framework": "^9.2.0", + "mockery/mockery": "^1.5.1", + "nunomaduro/larastan": "^2.2.0", "nunomaduro/termwind": "^1.14.0", "pestphp/pest": "^1.22.1" }, @@ -455,20 +442,20 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2022-09-13T15:07:15+00:00" + "time": "2022-11-29T16:25:20+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.11.0", + "version": "1.11.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", "shasum": "" }, "require": { @@ -506,7 +493,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" }, "funding": [ { @@ -514,20 +501,20 @@ "type": "tidelift" } ], - "time": "2022-03-03T13:19:32+00:00" + "time": "2023-03-08T13:26:56+00:00" }, { "name": "nikic/php-parser", - "version": "v4.15.2", + "version": "v4.15.4", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc" + "reference": "6bb5176bc4af8bcb7d926f88718db9b96a2d4290" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", - "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6bb5176bc4af8bcb7d926f88718db9b96a2d4290", + "reference": "6bb5176bc4af8bcb7d926f88718db9b96a2d4290", "shasum": "" }, "require": { @@ -568,9 +555,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.2" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.4" }, - "time": "2022-11-12T15:38:23+00:00" + "time": "2023-03-05T19:49:14+00:00" }, { "name": "phar-io/manifest", @@ -744,23 +731,23 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.19", + "version": "9.2.26", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559" + "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c77b56b63e3d2031bd8997fcec43c1925ae46559", - "reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/443bc6912c9bd5b409254a40f4b0f4ced7c80ea1", + "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.14", + "nikic/php-parser": "^4.15", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -775,8 +762,8 @@ "phpunit/phpunit": "^9.3" }, "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "type": "library", "extra": { @@ -809,7 +796,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.19" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.26" }, "funding": [ { @@ -817,7 +804,7 @@ "type": "github" } ], - "time": "2022-11-18T07:47:47+00:00" + "time": "2023-03-06T12:58:08+00:00" }, { "name": "phpunit/php-file-iterator", @@ -1062,20 +1049,20 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.26", + "version": "9.6.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "851867efcbb6a1b992ec515c71cdcf20d895e9d2" + "reference": "86e761949019ae83f49240b2f2123fb5ab3b2fc5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/851867efcbb6a1b992ec515c71cdcf20d895e9d2", - "reference": "851867efcbb6a1b992ec515c71cdcf20d895e9d2", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/86e761949019ae83f49240b2f2123fb5ab3b2fc5", + "reference": "86e761949019ae83f49240b2f2123fb5ab3b2fc5", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1", + "doctrine/instantiator": "^1.3.1 || ^2", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", @@ -1104,8 +1091,8 @@ "sebastian/version": "^3.0.2" }, "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" + "ext-soap": "To be able to generate mocks based on WSDL files", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "bin": [ "phpunit" @@ -1113,7 +1100,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.5-dev" + "dev-master": "9.6-dev" } }, "autoload": { @@ -1144,7 +1131,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.26" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.5" }, "funding": [ { @@ -1160,7 +1147,7 @@ "type": "tidelift" } ], - "time": "2022-10-28T06:00:21+00:00" + "time": "2023-03-09T06:34:10+00:00" }, { "name": "sebastian/cli-parser", @@ -1528,16 +1515,16 @@ }, { "name": "sebastian/environment", - "version": "5.1.4", + "version": "5.1.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", "shasum": "" }, "require": { @@ -1579,7 +1566,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" }, "funding": [ { @@ -1587,7 +1574,7 @@ "type": "github" } ], - "time": "2022-04-03T09:37:03+00:00" + "time": "2023-02-03T06:03:51+00:00" }, { "name": "sebastian/exporter", @@ -1901,16 +1888,16 @@ }, { "name": "sebastian/recursion-context", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", "shasum": "" }, "require": { @@ -1949,10 +1936,10 @@ } ], "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" }, "funding": [ { @@ -1960,7 +1947,7 @@ "type": "github" } ], - "time": "2020-10-26T13:17:30+00:00" + "time": "2023-02-03T06:07:39+00:00" }, { "name": "sebastian/resource-operations", @@ -2019,16 +2006,16 @@ }, { "name": "sebastian/type", - "version": "3.2.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", "shasum": "" }, "require": { @@ -2063,7 +2050,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" }, "funding": [ { @@ -2071,7 +2058,7 @@ "type": "github" } ], - "time": "2022-09-12T14:47:03+00:00" + "time": "2023-02-03T06:13:03+00:00" }, { "name": "sebastian/version", @@ -2219,9 +2206,18 @@ "time": "2021-07-28T10:34:58+00:00" } ], - "aliases": [], + "aliases": [ + { + "package": "utopia-php/balancer", + "version": "dev-feat-get-options", + "alias": "0.3.99", + "alias_normalized": "0.3.99.0" + } + ], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "utopia-php/balancer": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { From c28cdcdefeece0262c3f52c759f413088bb14936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Fri, 24 Mar 2023 10:01:40 +0100 Subject: [PATCH 2/8] Bug fixing during QA --- app/http.php | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/app/http.php b/app/http.php index 94f75d7..f06deca 100644 --- a/app/http.php +++ b/app/http.php @@ -131,11 +131,11 @@ return ($runtime['usage'] ?? 100) < 80; }); } - } - // Any options - $balancer2 = new Balancer($algorithm); - $balancer2->addFilter(fn ($option) => $option->getState('status', 'offline') === 'online'); + // Any options + $balancer2 = new Balancer($algorithm); + $balancer2->addFilter(fn ($option) => $option->getState('status', 'offline') === 'online'); + } foreach ($state as $stateItem) { if (App::isDevelopment()) { @@ -146,12 +146,17 @@ * @var array $stateItem */ $balancer1->addOption(new Option($stateItem)); - $balancer2->addOption(new Option($stateItem)); + + if(isset($balancer2)) { + $balancer2->addOption(new Option($stateItem)); + } } - $group - ->add($balancer1) - ->add($balancer2); + $group->add($balancer1); + + if(isset($balancer2)) { + $group->add($balancer2); + } return $group; }, ['algorithm', 'request']); From 2a9f00c27c67c5c5107798f1f7370fea1176964d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 7 Aug 2023 10:28:30 +0000 Subject: [PATCH 3/8] Add tests --- app/http.php | 4 ++-- tests/HTTPTest.php | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/app/http.php b/app/http.php index f06deca..50404ac 100644 --- a/app/http.php +++ b/app/http.php @@ -147,14 +147,14 @@ */ $balancer1->addOption(new Option($stateItem)); - if(isset($balancer2)) { + if (isset($balancer2)) { $balancer2->addOption(new Option($stateItem)); } } $group->add($balancer1); - if(isset($balancer2)) { + if (isset($balancer2)) { $group->add($balancer2); } diff --git a/tests/HTTPTest.php b/tests/HTTPTest.php index b26dd3a..3eb0efa 100644 --- a/tests/HTTPTest.php +++ b/tests/HTTPTest.php @@ -49,4 +49,43 @@ public function testBalancer(): void // Ensure secret is nessessary $this->assertEquals(401, $headers['status-code']); } + + public function testAddressingMethods(): void + { + $response = (array) $this->client->call(Client::METHOD_GET, '/v1/ping', [ + 'x-opr-addressing-method' => 'anycast-efficient' + ]); + $headers = (array) $response['headers']; + $body = (array) $response['body']; + + // Ensure response as sent from Mockoon + $this->assertEquals(200, $headers['status-code']); + $this->assertEquals('pong', $body['ping']); + $this->assertContains($body['server'], ['mockoon1', 'mockoon2']); + // Ensure proper executor secret + $this->assertEquals('Bearer executor-secret-key', $body['secret']); + + $response = (array) $this->client->call(Client::METHOD_GET, '/v1/ping', [ + 'x-opr-addressing-method' => 'anycast-fast' + ]); + $headers = (array) $response['headers']; + $body = (array) $response['body']; + + // Ensure response as sent from Mockoon + $this->assertEquals(200, $headers['status-code']); + $this->assertEquals('pong', $body['ping']); + $this->assertContains($body['server'], ['mockoon1', 'mockoon2']); + // Ensure proper executor secret + $this->assertEquals('Bearer executor-secret-key', $body['secret']); + + $response = (array) $this->client->call(Client::METHOD_GET, '/v1/ping', [ + 'x-opr-addressing-method' => 'broadcast' + ]); + $headers = (array) $response['headers']; + $body = $response['body']; + + $this->assertEquals(204, $headers['status-code']); + $this->assertEquals(0, $headers['content-length']); + $this->assertEquals('', $body); + } } From 5bdc76b0aacee66226abef7dccd1b389f1c850f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 7 Aug 2023 10:28:48 +0000 Subject: [PATCH 4/8] Upgrade balancer lib --- composer.json | 2 +- composer.lock | 89 ++++++++++++++++++++++++--------------------------- 2 files changed, 42 insertions(+), 49 deletions(-) diff --git a/composer.json b/composer.json index 3cd5ec5..8cd712e 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,7 @@ "utopia-php/registry": "0.6.*", "utopia-php/cli": "0.13.*", "utopia-php/logger": "0.3.*", - "utopia-php/balancer": "dev-feat-get-options as 0.3.99" + "utopia-php/balancer": "0.4.*" }, "require-dev": { "swoole/ide-helper": "4.8.5", diff --git a/composer.lock b/composer.lock index 6206118..1416dfd 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "74f859d1d9486d08095871b97196d376", + "content-hash": "7e8951a730ff2eee765499b5ed322d87", "packages": [ { "name": "utopia-php/balancer", - "version": "dev-feat-get-options", + "version": "0.4.0", "source": { "type": "git", "url": "https://github.com/utopia-php/balancer.git", - "reference": "42a61096c8f9ec81fd908d84618c73ef1914a021" + "reference": "b281cf22cba25429384cd792a9b0df83b5f9f938" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/balancer/zipball/42a61096c8f9ec81fd908d84618c73ef1914a021", - "reference": "42a61096c8f9ec81fd908d84618c73ef1914a021", + "url": "https://api.github.com/repos/utopia-php/balancer/zipball/b281cf22cba25429384cd792a9b0df83b5f9f938", + "reference": "b281cf22cba25429384cd792a9b0df83b5f9f938", "shasum": "" }, "require": { @@ -49,9 +49,9 @@ ], "support": { "issues": "https://github.com/utopia-php/balancer/issues", - "source": "https://github.com/utopia-php/balancer/tree/feat-get-options" + "source": "https://github.com/utopia-php/balancer/tree/0.4.0" }, - "time": "2023-03-16T12:17:42+00:00" + "time": "2023-08-07T10:26:14+00:00" }, { "name": "utopia-php/cli", @@ -505,16 +505,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.15.4", + "version": "v4.16.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "6bb5176bc4af8bcb7d926f88718db9b96a2d4290" + "reference": "19526a33fb561ef417e822e85f08a00db4059c17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6bb5176bc4af8bcb7d926f88718db9b96a2d4290", - "reference": "6bb5176bc4af8bcb7d926f88718db9b96a2d4290", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/19526a33fb561ef417e822e85f08a00db4059c17", + "reference": "19526a33fb561ef417e822e85f08a00db4059c17", "shasum": "" }, "require": { @@ -555,9 +555,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.4" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.16.0" }, - "time": "2023-03-05T19:49:14+00:00" + "time": "2023-06-25T14:52:30+00:00" }, { "name": "phar-io/manifest", @@ -731,16 +731,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.26", + "version": "9.2.27", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1" + "reference": "b0a88255cb70d52653d80c890bd7f38740ea50d1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/443bc6912c9bd5b409254a40f4b0f4ced7c80ea1", - "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/b0a88255cb70d52653d80c890bd7f38740ea50d1", + "reference": "b0a88255cb70d52653d80c890bd7f38740ea50d1", "shasum": "" }, "require": { @@ -796,7 +796,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.26" + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.27" }, "funding": [ { @@ -804,7 +805,7 @@ "type": "github" } ], - "time": "2023-03-06T12:58:08+00:00" + "time": "2023-07-26T13:44:30+00:00" }, { "name": "phpunit/php-file-iterator", @@ -1049,16 +1050,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.5", + "version": "9.6.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "86e761949019ae83f49240b2f2123fb5ab3b2fc5" + "reference": "a6d351645c3fe5a30f5e86be6577d946af65a328" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/86e761949019ae83f49240b2f2123fb5ab3b2fc5", - "reference": "86e761949019ae83f49240b2f2123fb5ab3b2fc5", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a6d351645c3fe5a30f5e86be6577d946af65a328", + "reference": "a6d351645c3fe5a30f5e86be6577d946af65a328", "shasum": "" }, "require": { @@ -1131,7 +1132,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.5" + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.10" }, "funding": [ { @@ -1147,7 +1149,7 @@ "type": "tidelift" } ], - "time": "2023-03-09T06:34:10+00:00" + "time": "2023-07-10T04:04:23+00:00" }, { "name": "sebastian/cli-parser", @@ -1449,16 +1451,16 @@ }, { "name": "sebastian/diff", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131", + "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131", "shasum": "" }, "require": { @@ -1503,7 +1505,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.5" }, "funding": [ { @@ -1511,7 +1513,7 @@ "type": "github" } ], - "time": "2020-10-26T13:10:38+00:00" + "time": "2023-05-07T05:35:17+00:00" }, { "name": "sebastian/environment", @@ -1655,16 +1657,16 @@ }, { "name": "sebastian/global-state", - "version": "5.0.5", + "version": "5.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" + "reference": "bde739e7565280bda77be70044ac1047bc007e34" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bde739e7565280bda77be70044ac1047bc007e34", + "reference": "bde739e7565280bda77be70044ac1047bc007e34", "shasum": "" }, "require": { @@ -1707,7 +1709,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.6" }, "funding": [ { @@ -1715,7 +1717,7 @@ "type": "github" } ], - "time": "2022-02-14T08:28:10+00:00" + "time": "2023-08-02T09:26:13+00:00" }, { "name": "sebastian/lines-of-code", @@ -2206,18 +2208,9 @@ "time": "2021-07-28T10:34:58+00:00" } ], - "aliases": [ - { - "package": "utopia-php/balancer", - "version": "dev-feat-get-options", - "alias": "0.3.99", - "alias_normalized": "0.3.99.0" - } - ], + "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "utopia-php/balancer": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { From cfa66f2ebbd04a84cc3b3522b2de1e0bb5a783f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Mon, 7 Aug 2023 10:31:06 +0000 Subject: [PATCH 5/8] Define const for addressing methods --- app/http.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/app/http.php b/app/http.php index 50404ac..2150301 100644 --- a/app/http.php +++ b/app/http.php @@ -30,6 +30,10 @@ use Utopia\Swoole\Request; use Utopia\Swoole\Response; +const ADDRESSING_METHOD_ANYCAST_EFFICIENT = 'anycast-efficient'; +const ADDRESSING_METHOD_ANYCAST_FAST = 'anycast-fast'; +const ADDRESSING_METHOD_ANYCAST_BROADCSAT = 'broadcast'; + Runtime::enableCoroutine(true, SWOOLE_HOOK_ALL); App::setMode((string) App::getEnv('OPR_PROXY_ENV', App::MODE_TYPE_PRODUCTION)); @@ -86,11 +90,11 @@ App::setResource('balancer', function (Algorithm $algorithm, Request $request) { global $state; $runtimeId = $request->getHeader('x-opr-runtime-id', ''); - $method = $request->getHeader('x-opr-addressing-method', 'anycast-efficient'); + $method = $request->getHeader('x-opr-addressing-method', ADDRESSING_METHOD_ANYCAST_EFFICIENT); $group = new Group(); - if ($method === 'anycast-fast') { + if ($method === ADDRESSING_METHOD_ANYCAST_FAST) { $algorithm = new Random(); } @@ -100,7 +104,7 @@ // Only online executors $balancer1->addFilter(fn ($option) => $option->getState('status', 'offline') === 'online'); - if ($method === 'anycast-efficient') { + if ($method === ADDRESSING_METHOD_ANYCAST_EFFICIENT) { // Only low host-cpu usage $balancer1->addFilter(function ($option) { /** @@ -254,7 +258,7 @@ function logError(Throwable $error, string $action, ?Logger $logger, Utopia\Rout ->inject('request') ->inject('response') ->action(function (Group $balancer, Request $request, Response $response) { - $method = $request->getHeader('x-opr-addressing-method', 'anycast-efficient'); + $method = $request->getHeader('x-opr-addressing-method', ADDRESSING_METHOD_ANYCAST_EFFICIENT); $proxyRequest = function (string $hostname) use ($request) { if (App::isDevelopment()) { @@ -353,7 +357,7 @@ function logError(Throwable $error, string $action, ?Logger $logger, Utopia\Rout ]; }; - if ($method === 'broadcast') { + if ($method === ADDRESSING_METHOD_ANYCAST_BROADCSAT) { foreach ($balancer->getOptions() as $option) { /** * @var string $hostname From 5428952e3d317a56d04da74ea4e34d8eab8ec9c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Tue, 8 Aug 2023 19:17:33 +0000 Subject: [PATCH 6/8] PR review changes --- app/http.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/http.php b/app/http.php index a28d7b2..eb307e1 100644 --- a/app/http.php +++ b/app/http.php @@ -32,7 +32,7 @@ const ADDRESSING_METHOD_ANYCAST_EFFICIENT = 'anycast-efficient'; const ADDRESSING_METHOD_ANYCAST_FAST = 'anycast-fast'; -const ADDRESSING_METHOD_ANYCAST_BROADCSAT = 'broadcast'; +const ADDRESSING_METHOD_BROADCSAT = 'broadcast'; Runtime::enableCoroutine(true, SWOOLE_HOOK_ALL); @@ -358,7 +358,7 @@ function logError(Throwable $error, string $action, ?Logger $logger, Utopia\Rout ]; }; - if ($method === ADDRESSING_METHOD_ANYCAST_BROADCSAT) { + if ($method === ADDRESSING_METHOD_BROADCSAT) { foreach ($balancer->getOptions() as $option) { /** * @var string $hostname From 2f6f998bbab552991a1b057c58ea4f03792a6a13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Wed, 9 Aug 2023 07:24:46 +0000 Subject: [PATCH 7/8] Simplify header parser --- app/http.php | 45 ++++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/app/http.php b/app/http.php index eb307e1..77158b5 100644 --- a/app/http.php +++ b/app/http.php @@ -305,11 +305,24 @@ function logError(Throwable $error, string $action, ?Logger $logger, Utopia\Rout $ch = \curl_init(); + $$responseHeaders = []; + \curl_setopt($ch, CURLOPT_URL, $hostname . $request->getURI()); \curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request->getMethod()); \curl_setopt($ch, CURLOPT_POSTFIELDS, $body); \curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - \curl_setopt($ch, CURLOPT_HEADER, true); + \curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($curl, $header) use (&$responseHeaders) { + $len = strlen($header); + $header = explode(':', $header, 2); + if (count($header) < 2) { // ignore invalid headers + return $len; + } + + $key = strtolower(trim($header[0])); + $responseHeaders[$key] = trim($header[1]); + + return $len; + }); \curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); \curl_setopt($ch, CURLOPT_TIMEOUT, \intval(App::getEnv('OPR_PROXY_MAX_TIMEOUT', '900'))); @@ -318,43 +331,24 @@ function logError(Throwable $error, string $action, ?Logger $logger, Utopia\Rout $curlHeaders[] = "{$header}: {$value}"; } + \curl_setopt($ch, CURLOPT_HEADEROPT, CURLHEADER_UNIFIED); \curl_setopt($ch, CURLOPT_HTTPHEADER, $curlHeaders); - $executorResponse = \curl_exec($ch); - + $body = \curl_exec($ch); $statusCode = \curl_getinfo($ch, CURLINFO_HTTP_CODE); - $error = \curl_error($ch); - $errNo = \curl_errno($ch); - $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); - $headers = substr(\strval($executorResponse), 0, $header_size); - $body = substr(\strval($executorResponse), $header_size); - \curl_close($ch); - if ($errNo !== 0) { + if ($errNo !== 0 || \is_bool($body)) { throw new Exception('Unexpected curl error between proxy and executor ID ' . $hostname . ' (' . $errNo . '): ' . $error); } - $headersArr = []; - if (!empty($headers)) { - $headers = preg_split("/\r\n|\n|\r/", $headers); - if ($headers) { - foreach ($headers as $header) { - if (\str_contains($header, ':')) { - [$key, $value] = \explode(':', $header, 2); - $headersArr[$key] = $value; - } - } - } - } - return [ 'statusCode' => $statusCode, 'body' => $body, - 'headers' => $headersArr + 'headers' => $responseHeaders ]; }; @@ -382,8 +376,9 @@ function logError(Throwable $error, string $action, ?Logger $logger, Utopia\Rout $hostname = $option->getState('hostname') ?? ''; $result = $proxyRequest($hostname); + $headers = $result['headers'] ?? []; - foreach ($result['headers'] as $key => $value) { + foreach ($headers as $key => $value) { $response->addHeader($key, $value); } From 780e6c63b710e7fc817cd3c9ab87d9f91cbd8057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Wed, 9 Aug 2023 09:40:06 +0200 Subject: [PATCH 8/8] Fix variable name --- app/http.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/http.php b/app/http.php index 77158b5..55ab1e5 100644 --- a/app/http.php +++ b/app/http.php @@ -32,7 +32,7 @@ const ADDRESSING_METHOD_ANYCAST_EFFICIENT = 'anycast-efficient'; const ADDRESSING_METHOD_ANYCAST_FAST = 'anycast-fast'; -const ADDRESSING_METHOD_BROADCSAT = 'broadcast'; +const ADDRESSING_METHOD_BROADCAST = 'broadcast'; Runtime::enableCoroutine(true, SWOOLE_HOOK_ALL); @@ -352,7 +352,7 @@ function logError(Throwable $error, string $action, ?Logger $logger, Utopia\Rout ]; }; - if ($method === ADDRESSING_METHOD_BROADCSAT) { + if ($method === ADDRESSING_METHOD_BROADCAST) { foreach ($balancer->getOptions() as $option) { /** * @var string $hostname