From cd87c299dc1cb5d19bdb82dac438d4d08992f59b Mon Sep 17 00:00:00 2001 From: osaajani Date: Sun, 8 Dec 2019 01:50:18 +0100 Subject: [PATCH] add abstract daemon --- daemons/AbstractDaemon.php | 129 +++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 daemons/AbstractDaemon.php diff --git a/daemons/AbstractDaemon.php b/daemons/AbstractDaemon.php new file mode 100644 index 0000000..1148b78 --- /dev/null +++ b/daemons/AbstractDaemon.php @@ -0,0 +1,129 @@ +name = $name; + $this->signals = array_merge($this->signals, $signals); + + //Allow script to run indefinitly + set_time_limit(0); + + //Register signals + $this->register_signals(); + } + + + /** + * Used to register POSIX signals + */ + private function register_signals() + { + //Enable a tick at every 1 instruction, allowing us to run a function frequently, for exemple looking at signal status + declare(ticks = 1); + + foreach ($this->signals as $signal) + { + //For each signal define the method handle_signal of the current class as the way to handle it + @pcntl_signal($signal, [ + 'self', + 'handle_signal' + ]); + } + } + + /** + * Used to handle properly SIGINT, SIGTERM, SIGCHLD and SIGHUP + * + * @param int $signal + * @param mixed $signinfo + */ + protected function handle_signal(int $signal, $signinfo) + { + if ($signal == SIGTERM || $signal == SIGINT) //Stop the daemon + { + $this->is_running = false; + } + else if ($signal == SIGHUP) //Restart the daemon + { + $this->on_stop(); + $this->on_start(); + } + else if ($signal == SIGCHLD) //On daemon child stopping + { + pcntl_waitpid(-1, $status, WNOHANG); + } + else //All the other signals + { + $this->handle_other_signals($signal); + } + } + + + /** + * Launch the infinite loop executing the "run" abstract method + */ + protected function start () + { + $this->on_start(); + while ($this->is_running) + { + pcntl_signal_dispatch(); //Call dispatcher for signals + $this->run(); + } + $this->on_stop(); + } + + + /** + * True if the daemon is running + */ + public function is_running() + { + return $this->is_running; + } + + /** + * Override to implement the code that run infinetly (actually, it run one time but repeat the operation infinetly + */ + protected abstract function run(); + + + /** + * Override to execute code before the ''run'' method on daemon start + */ + protected abstract function on_start(); + + + /** + * Override to execute code after the ''run'' method on daemon shutdown + */ + protected abstract function on_stop(); + + + /** + * Override to handle additional POSIX signals + * + * @param int $signal : Signal sent by interrupt + */ + protected abstract function handle_other_signals(int $signal); +}