Skip to content

Signal Handling

Jason M edited this page Jun 5, 2017 · 2 revisions

Synopsis

The core Daemon class will automatically catch all known signals once it is initialized (call run()). User code should never call pcntl_signal() to capture your own signals. You will override the signal handler that the Daemon sets up already for you. For example, if you override the SIGCHLD signal, you'll completely break the ProcessManager and you'll end up with zombie processes and potentially stuck Workers.

For more information on what events you can capture in your Daemon, see Events.

To capture any signal within your application you should listen for the DaemonEvent::ON_SIGNAL event. See the example below:

use Lifo\Daemon\Daemon;
use Lifo\Daemon\Event\DaemonEvent;
use Lifo\Daemon\Event\SignalEvent;
class MyDaemon extends Daemon {
    private $signals = [];
    protected function initialize() {
        $this->on(DaemonEvent::ON_SIGNAL, function(SignalEvent $e) {
            // this callback should do as little as possible!
            $this->signals[] = $e->getSignal();
        });
    }

    protected function execute() {
        if ($this->signals) {
            $this->log("Hey! I caught %d signal%s: %s. Isn't that wonderful?!", 
                       count($this->signals),
                       count($this->signals) == 1 ? '' : 's',
                       implode(', ', $this->signals));
            $this->signals = [];
        }
    }
}

Non reentrant

Your signal callback is a special case where you need to do as little as possible. Signals are non reentrant. Meaning, once a signal is caught, that signal will not be caught again until your callback finishes.

Normally, you'll simply catch a signal, set a flag and then at the next loop iteration you should act on that flag and then reset the flag. So you're ready to catch the next signal. If your loop interval is set really high (5+ seconds) you may have a noticeable delay in your application in catching signals. So, plan and test properly.

Clone this wiki locally