Created
January 9, 2023 15:45
-
-
Save vudaltsov/e9df49a5d003f9e3df58d0766e572c95 to your computer and use it in GitHub Desktop.
WaitCommand.php
This file contains 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
vendor: composer.json composer.lock | |
composer install | |
touch vendor | |
db: vendor | |
php bin/console wait $(DB_HOST):$(DB_PORT) | |
php bin/console doctrine:database:create --if-not-exists | |
php bin/console doctrine:migrations:migrate --no-interaction | |
.PHONY: db |
This file contains 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
<?php | |
declare(strict_types=1); | |
namespace Infrastructure\Wait; | |
use Symfony\Component\Console\Attribute\AsCommand; | |
use Symfony\Component\Console\Command\Command; | |
use Symfony\Component\Console\Input\InputArgument; | |
use Symfony\Component\Console\Input\InputInterface; | |
use Symfony\Component\Console\Input\InputOption; | |
use Symfony\Component\Console\Output\OutputInterface; | |
#[AsCommand('wait')] | |
final class WaitCommand extends Command | |
{ | |
private const DEFAULT_TIMEOUT_MS = 5_000; | |
private const DEFAULT_INTERVAL_MS = 200; | |
protected function configure(): void | |
{ | |
$this | |
->addArgument('host', InputArgument::REQUIRED) | |
->addOption('timeout', mode: InputOption::VALUE_REQUIRED, description: 'Timeout in milliseconds.', default: self::DEFAULT_TIMEOUT_MS) | |
->addOption('interval', mode: InputOption::VALUE_REQUIRED, description: 'Interval in milliseconds.', default: self::DEFAULT_INTERVAL_MS) | |
; | |
} | |
protected function execute(InputInterface $input, OutputInterface $output): int | |
{ | |
$host = $input->getArgument('host'); | |
\assert($host !== ''); | |
$timeoutMs = (int) $input->getOption('timeout'); | |
\assert($timeoutMs > 0); | |
$intervalUs = (int) $input->getOption('interval') * 1000; | |
\assert($intervalUs > 0); | |
$till = new \DateTimeImmutable(sprintf('+%d milliseconds', $timeoutMs)); | |
$printedWait = false; | |
do { | |
if (@fsockopen($host)) { | |
$output->success(sprintf('%s is up', $host)); | |
return self::SUCCESS; | |
} | |
if (!$printedWait) { | |
$output->comment(sprintf('Waiting for <info>%s</info>...', $host)); | |
$printedWait = true; | |
} | |
usleep($intervalUs); | |
} while (new \DateTimeImmutable() < $till); | |
$output->error(sprintf('Failed to connect to %s in %d ms.', $host, $timeoutMs)); | |
return self::FAILURE; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment