Skip to content

Commit 5410217

Browse files
committed
Support cancelling the activity on Ctrl+C (non-Windows)
1 parent 2a893f5 commit 5410217

File tree

1 file changed

+61
-4
lines changed

1 file changed

+61
-4
lines changed

src/Service/ActivityMonitor.php

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Platformsh\Cli\Service;
44

5+
use GuzzleHttp\Exception\BadResponseException;
56
use Platformsh\Client\Model\Activity;
67
use Platformsh\Client\Model\ActivityLog\LogItem;
78
use Platformsh\Client\Model\Project;
@@ -99,6 +100,27 @@ public function waitAndLog(Activity $activity, $pollInterval = 3, $timestamps =
99100
return Helper::formatTime(time() - $startTime);
100101
});
101102
$bar->setFormat('[%bar%] %elapsed:6s% (%state%)');
103+
104+
// Set up cancellation for the activity on Ctrl+C.
105+
if (\function_exists('\\pcntl_signal') && $activity->operationAvailable('cancel')) {
106+
declare(ticks = 1);
107+
$sigintReceived = false;
108+
/** @noinspection PhpComposerExtensionStubsInspection */
109+
\pcntl_signal(SIGINT, function () use ($activity, $stdErr, $bar, &$sigintReceived) {
110+
if ($sigintReceived) {
111+
exit(1);
112+
}
113+
$sigintReceived = true;
114+
$bar->clear();
115+
if ($this->cancel($activity, $stdErr)) {
116+
exit(1);
117+
}
118+
$stdErr->writeln('');
119+
$bar->advance();
120+
});
121+
$stdErr->writeln('Enter Ctrl+C once to cancel the activity (or twice to quit this command).');
122+
}
123+
102124
$bar->start();
103125

104126
$logStream = $this->getLogStream($activity, $bar);
@@ -166,6 +188,40 @@ public function waitAndLog(Activity $activity, $pollInterval = 3, $timestamps =
166188
return false;
167189
}
168190

191+
/**
192+
* Attempts to cancel the activity, catching and printing errors.
193+
*
194+
* @param Activity $activity
195+
* @param OutputInterface $stdErr
196+
*
197+
* @return bool
198+
*/
199+
private function cancel(Activity $activity, OutputInterface $stdErr)
200+
{
201+
if (!$activity->operationAvailable('cancel')) {
202+
$stdErr->writeln('The activity cannot be cancelled.');
203+
return false;
204+
}
205+
$stdErr->writeln('Cancelling the activity...');
206+
try {
207+
try {
208+
$activity->cancel();
209+
} catch (BadResponseException $e) {
210+
if ($e->getResponse() && $e->getResponse()->getStatusCode() === 400 && \strpos($e->getMessage(), 'cannot be cancelled in its current state')) {
211+
$activity->refresh();
212+
$stdErr->writeln(\sprintf('The activity cannot be cancelled in its current state (<error>%s</error>).', $activity->state));
213+
return false;
214+
}
215+
throw $e;
216+
}
217+
} catch (\Exception $e) {
218+
$stdErr->writeln(\sprintf('Failed to cancel the activity: <error>%s</error>', $e->getMessage()));
219+
return false;
220+
}
221+
$stdErr->writeln('The activity was successfully cancelled.');
222+
return true;
223+
}
224+
169225
/**
170226
* Reads the log stream and returns LogItem objects.
171227
*
@@ -435,11 +491,11 @@ private function getStart(Activity $activity) {
435491
private function getLogStream(Activity $activity, ProgressBar $bar) {
436492
$url = $activity->getLink('log');
437493

438-
// Try fetching the stream with a 10 second timeout per call, and a .5
439-
// second interval between calls, for up to 2 minutes.
440-
$readTimeout = 10;
441-
$interval = .5;
494+
// Try fetching the stream with an up to 10 second timeout per call,
495+
// and a .5 second interval between calls, for up to 2 minutes.
496+
$readTimeout = .5;
442497
$stream = \fopen($url, 'r', false, $this->api->getStreamContext($readTimeout));
498+
$interval = .5;
443499
$start = \microtime(true);
444500
while ($stream === false) {
445501
if (\microtime(true) - $start > 120) {
@@ -448,6 +504,7 @@ private function getLogStream(Activity $activity, ProgressBar $bar) {
448504
$bar->advance();
449505
\usleep($interval * 1000000);
450506
$bar->advance();
507+
$readTimeout = $readTimeout >= 10 ? $readTimeout : $readTimeout + .5;
451508
$stream = \fopen($url, 'r', false, $this->api->getStreamContext($readTimeout));
452509
}
453510
\stream_set_blocking($stream, 0);

0 commit comments

Comments
 (0)