From cd9c44d1079de3d2f8bfbdd6d70ad6d8bacbd88a Mon Sep 17 00:00:00 2001 From: Jigar Mehta Date: Sat, 27 May 2023 13:39:14 -0300 Subject: [PATCH] WIP: Handle SIGINT gracefully --- src/Command/ExecCommand.php | 43 ++++++++++++++++++++++++++-- src/Trait/SiteDetectorAwareTrait.php | 2 +- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/Command/ExecCommand.php b/src/Command/ExecCommand.php index f5d6f32..c50973e 100644 --- a/src/Command/ExecCommand.php +++ b/src/Command/ExecCommand.php @@ -12,6 +12,7 @@ use Drall\Model\EnvironmentId; use Drall\Model\Placeholder; use Drall\Model\RawCommand; +use Drall\Trait\SignalAwareTrait; use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -24,6 +25,8 @@ */ class ExecCommand extends BaseCommand { + use SignalAwareTrait; + /** * Maximum number of Drall workers. * @@ -163,11 +166,37 @@ protected function execute(InputInterface $input, OutputInterface $output): int ); $exitCode = 0; - Loop::run(function () use ($values, $command, $placeholder, $output, $progressBar, $workers, &$exitCode) { + $isStopping = FALSE; + $this->registerSignalListener(SIGINT, function () use (&$isStopping, $output) { + $output->writeln(''); + + if ($isStopping) { + $this->logger->error('Interrupted by user.'); + exit(1); + } + + $this->logger->warning('Stopping after current item.'); + $isStopping = TRUE; + }); + + Loop::run(function () use ( + $values, + $command, + $placeholder, + $output, + $progressBar, + $workers, + &$exitCode, + &$isStopping + ) { yield ConcurrentIterator\each( Iterator\fromIterable($values), new LocalSemaphore($workers), - function ($value) use ($command, $placeholder, $output, $progressBar, &$exitCode) { + function ($value) use ($command, $placeholder, $output, $progressBar, &$exitCode, &$isStopping) { + if ($isStopping) { + return; + } + $sCommand = Placeholder::replace([$placeholder->value => $value], $command); $process = new Process("($sCommand) 2>&1", getcwd()); @@ -189,9 +218,17 @@ function ($value) use ($command, $placeholder, $output, $progressBar, &$exitCode ); }); - $progressBar->finish(); + if (!$isStopping) { + $progressBar->finish(); + } + $output->writeln(''); + if ($isStopping) { + $this->logger->error('Interrupted by user.'); + return 1; + } + return $exitCode; } diff --git a/src/Trait/SiteDetectorAwareTrait.php b/src/Trait/SiteDetectorAwareTrait.php index 6a516d7..73e72a7 100644 --- a/src/Trait/SiteDetectorAwareTrait.php +++ b/src/Trait/SiteDetectorAwareTrait.php @@ -30,7 +30,7 @@ public function setSiteDetector(SiteDetector $siteDetector) { public function siteDetector(): SiteDetector { if (!$this->hasSiteDetector()) { throw new \BadMethodCallException( - 'A site detecetor instance must first be assigned' + 'A site detector instance must first be assigned' ); }