Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#!/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
You can’t perform that action at this time.