Created
February 11, 2020 10:04
-
-
Save Ocramius/b1bac3d5491c1469fa3b466dbd3b09ea to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env php | |
<?php | |
declare(strict_types=1); | |
namespace WaitForElasticsearch; | |
use InvalidArgumentException; | |
use UnexpectedValueException; | |
use function curl_close; | |
use function curl_exec; | |
use function curl_getinfo; | |
use function curl_init; | |
use function error_log; | |
use function getenv; | |
use function is_string; | |
use function microtime; | |
use function sprintf; | |
use function usleep; | |
use const CURLINFO_HTTP_CODE; | |
use const CURLOPT_HEADER; | |
use const CURLOPT_RETURNTRANSFER; | |
use const CURLOPT_TIMEOUT_MS; | |
use const CURLOPT_URL; | |
// Note: this is a dependency-less file that only relies on ext-curl to function. We do not want any dependencies in | |
// here, since the system may not yet be in functional state at this stage. | |
(static function () : void { | |
$elasticsearch = getenv('ELASTICSEARCH_URL'); | |
if (! is_string($elasticsearch)) { | |
throw new InvalidArgumentException('Missing "ELASTICSEARCH_URL" environment variable'); | |
} | |
$timeLimit = (float) (getenv('ELASTICSEARCH_WAIT_TIMEOUT_SECONDS') ?: 60.0); | |
$retryInterval = (int) ((((float) getenv('ELASTICSEARCH_RETRY_INTERVAL_SECONDS')) ?: 0.5) * 1000000); | |
$start = microtime(true); | |
$elapsedTime = static function () use ($start) : float { | |
return microtime(true) - $start; | |
}; | |
$remainingTime = static function () use ($elapsedTime, $timeLimit) : float { | |
return $timeLimit - $elapsedTime(); | |
}; | |
while ($remainingTime() > 0) { | |
$curl = curl_init(); | |
// @see https://www.elastic.co/guide/en/elasticsearch/reference/current/cluster-health.html | |
curl_setopt($curl, CURLOPT_HEADER, 0); | |
curl_setopt($curl, CURLOPT_TIMEOUT_MS, 500); | |
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); | |
curl_setopt( | |
$curl, | |
CURLOPT_URL, | |
$elasticsearch . sprintf('/_cluster/health?wait_for_status=yellow&timeout=%ds', (int) $timeLimit) | |
); | |
$response = curl_exec($curl); | |
$errorCode = curl_errno($curl); | |
$errorMessage = curl_error($curl); | |
$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); | |
curl_close($curl); | |
if ($errorCode === 0) { | |
/** @noinspection ForgottenDebugOutputInspection */ | |
error_log(sprintf('ElasticSearch connection succeeded after %.2f seconds', $elapsedTime())); | |
if ($statusCode === 200) { | |
/** @noinspection ForgottenDebugOutputInspection */ | |
error_log(sprintf( | |
'ElasticSearch status is (at least) yellow after %.2f seconds with response: %s', | |
$elapsedTime(), | |
$response | |
)); | |
return; | |
} | |
/** @noinspection ForgottenDebugOutputInspection */ | |
error_log(sprintf( | |
'ElasticSearch status is pending after %.2f seconds with response code %d', | |
$elapsedTime(), | |
$statusCode | |
)); | |
} | |
if ($errorCode !== 0) { | |
/** @noinspection ForgottenDebugOutputInspection */ | |
error_log(sprintf( | |
'Failed to contact ElasticSearch: curl error "%s", code %d, retrying for another %.2f seconds', | |
$errorMessage, | |
$errorCode, | |
$remainingTime() | |
)); | |
} | |
usleep($retryInterval); | |
} | |
throw new UnexpectedValueException(sprintf('Failed to connect to Elasticsearch after %.2f seconds', $elapsedTime())); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment