Skip to content

Instantly share code, notes, and snippets.

@vudaltsov
Created January 9, 2023 15:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vudaltsov/e9df49a5d003f9e3df58d0766e572c95 to your computer and use it in GitHub Desktop.
Save vudaltsov/e9df49a5d003f9e3df58d0766e572c95 to your computer and use it in GitHub Desktop.
WaitCommand.php
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
<?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