Skip to content

Commit

Permalink
Add initial signal watcher to kill app (#106)
Browse files Browse the repository at this point in the history
* Add initial signal watcher to kill app

In practice not responding to SIGINT caused end users to forcefully shut
down the underlying architecture running the application. This could
mean forcefully killing docker containers as oppoased to gracefully
handling exit requests. This submits an initial, untested,
implementation to watch for signals to quit the app.

* put a wrapper around pcntl extension for now

* better extension checking

* make sure var is defined
  • Loading branch information
cspray authored May 1, 2021
1 parent 8755b61 commit f3c1aac
Showing 1 changed file with 20 additions and 3 deletions.
23 changes: 20 additions & 3 deletions src/AmpEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,26 @@ public function run(Application $application) : void {
throw $exception;
}

Loop::setErrorHandler(function(Throwable $error) use($application) {
$signalWatcher = null;
if (Loop::get() instanceof Loop\NativeDriver && extension_loaded('pcntl')) {
$signalWatcher = Loop::onSignal(SIGINT, function() use($application, &$signalWatcher) {
if ($this->engineState->isRunning()) {
yield $application->stop();
yield $this->emitEngineShutDownEvent($application);
}
Loop::disable($signalWatcher);
exit;
});
}

Loop::setErrorHandler(function(Throwable $error) use($application, $signalWatcher) {
// This is here to ensure we guard against the possibility that some event listener in
// emitEngineShutDownEvent throws an exception which would cause the Loop error handler to be called
// again, which would cause the process powering our app to go into an infinite loop until maximum memory
// is used.
if (isset($signalWatcher)) {
Loop::disable($signalWatcher);
}
if (!$this->engineState->isCrashed()) {
$this->engineState = EngineState::Crashed();
$application->handleException($error);
Expand All @@ -97,8 +112,7 @@ public function run(Application $application) : void {
}
});


Loop::run(function() use($application) {
Loop::run(function() use($application, $signalWatcher) {
$this->engineState = EngineState::Running();

if (!$this->engineBooted) {
Expand All @@ -122,6 +136,9 @@ public function run(Application $application) : void {
yield $this->emitEngineShutDownEvent($application);
$this->logger->info('Completed Application cleanup process. Engine shutting down.');
$this->engineState = EngineState::Idle();
if (isset($signalWatcher)) {
Loop::disable($signalWatcher);
}
});
}

Expand Down

0 comments on commit f3c1aac

Please sign in to comment.