diff --git a/lib/util/daemon.php b/lib/util/daemon.php index eaeecc1058..25097b0ea8 100644 --- a/lib/util/daemon.php +++ b/lib/util/daemon.php @@ -1,68 +1,56 @@ . - */ +// This file is part of GNU social - https://www.gnu.org/software/social +// +// GNU social is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// GNU social is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with GNU social. If not, see . -if (!defined('STATUSNET') && !defined('LACONICA')) { - exit(1); -} +defined('GNUSOCIAL') || die(); class Daemon { - var $daemonize = true; - var $_id = 'generic'; + public $daemonize = true; + public $_id = 'generic'; - function __construct($daemonize = true) + public function __construct($daemonize = true) { $this->daemonize = $daemonize; } - function name() + public function name() { return null; } - function get_id() + public function get_id() { return $this->_id; } - function set_id($id) + public function set_id($id) { $this->_id = $id; } - function background() + public function background() { - /* - * This prefers to Starting PHP 5.4 (dotdeb), maybe earlier for some version/distrib - * seems MySQL connection using mysqli driver get lost when fork. - * Need to unset it so that child process recreate it. - * - * @todo FIXME cleaner way to do it ? - */ - global $_DB_DATAOBJECT; - unset($_DB_DATAOBJECT['CONNECTIONS']); + // Database connection will likely get lost after forking + $this->resetDb(); $pid = pcntl_fork(); if ($pid < 0) { // error common_log(LOG_ERR, "Could not fork."); return false; - } else if ($pid > 0) { // parent + } elseif ($pid > 0) { // parent common_log(LOG_INFO, "Successfully forked."); exit(0); } else { // child @@ -70,7 +58,7 @@ class Daemon } } - function alreadyRunning() + public function alreadyRunning() { $pidfilename = $this->pidFilename(); @@ -89,7 +77,7 @@ class Daemon } } - function writePidFile() + public function writePidFile() { $pidfilename = $this->pidFilename(); @@ -100,7 +88,7 @@ class Daemon return file_put_contents($pidfilename, posix_getpid() . "\n"); } - function clearPidFile() + public function clearPidFile() { $pidfilename = $this->pidFilename(); if (!$pidfilename) { @@ -109,7 +97,7 @@ class Daemon return unlink($pidfilename); } - function pidFilename() + public function pidFilename() { $piddir = common_config('daemon', 'piddir'); if (!$piddir) { @@ -122,15 +110,17 @@ class Daemon return $piddir . '/' . $name . '.pid'; } - function changeUser() + public function changeUser() { $groupname = common_config('daemon', 'group'); if ($groupname) { $group_info = posix_getgrnam($groupname); if (!$group_info) { - common_log(LOG_WARNING, - 'Ignoring unknown group for daemon: ' . $groupname); + common_log( + LOG_WARNING, + 'Ignoring unknown group for daemon: ' . $groupname + ); } else { common_log(LOG_INFO, "Setting group to " . $groupname); posix_setgid($group_info['gid']); @@ -142,8 +132,10 @@ class Daemon if ($username) { $user_info = posix_getpwnam($username); if (!$user_info) { - common_log(LOG_WARNING, - 'Ignoring unknown user for daemon: ' . $username); + common_log( + LOG_WARNING, + 'Ignoring unknown user for daemon: ' . $username + ); } else { common_log(LOG_INFO, "Setting user to " . $username); posix_setuid($user_info['uid']); @@ -151,7 +143,7 @@ class Daemon } } - function runOnce() + public function runOnce() { if ($this->alreadyRunning()) { common_log(LOG_INFO, $this->name() . ' already running. Exiting.'); @@ -169,7 +161,7 @@ class Daemon $this->clearPidFile(); } - function run() + public function run() { return true; } diff --git a/lib/util/spawningdaemon.php b/lib/util/spawningdaemon.php index 732237403d..3eb5e72e4b 100644 --- a/lib/util/spawningdaemon.php +++ b/lib/util/spawningdaemon.php @@ -1,21 +1,20 @@ . - */ +// This file is part of GNU social - https://www.gnu.org/software/social +// +// GNU social is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// GNU social is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with GNU social. If not, see . + +defined('GNUSOCIAL') || die(); /** * Base class for daemon that can launch one or more processing threads, @@ -24,7 +23,7 @@ * This is mainly intended for indefinite workloads such as monitoring * a queue or maintaining an IM channel. * - * Child classes should implement the + * Child classes should implement the * * We can then pass individual items through the QueueHandler subclasses * they belong to. We additionally can handle queues for multiple sites. @@ -34,14 +33,14 @@ */ abstract class SpawningDaemon extends Daemon { - protected $threads=1; + protected $threads = 1; const EXIT_OK = 0; const EXIT_ERR = 1; const EXIT_SHUTDOWN = 100; const EXIT_RESTART = 101; - function __construct($id=null, $daemonize=true, $threads=1) + public function __construct($id = null, $daemonize = true, $threads = 1) { parent::__construct($daemonize); @@ -56,7 +55,7 @@ abstract class SpawningDaemon extends Daemon * * @return int exit code; use self::EXIT_SHUTDOWN to request not to respawn. */ - public abstract function runThread(); + abstract public function runThread(); /** * Spawn one or more background processes and let them start running. @@ -69,17 +68,17 @@ abstract class SpawningDaemon extends Daemon * though ParallelizingDaemon is probably better for workloads * that have forseeable endpoints. */ - function run() + public function run() { $this->initPipes(); - $children = array(); + $children = []; for ($i = 1; $i <= $this->threads; $i++) { $pid = pcntl_fork(); if ($pid < 0) { $this->log(LOG_ERR, "Couldn't fork for thread $i; aborting\n"); exit(1); - } else if ($pid == 0) { + } elseif ($pid === 0) { $this->initAndRunChild($i); } else { $this->log(LOG_INFO, "Spawned thread $i as pid $pid"); @@ -87,7 +86,7 @@ abstract class SpawningDaemon extends Daemon } sleep(common_config('queue', 'spawndelay')); } - + $this->log(LOG_INFO, "Waiting for children to complete."); while (count($children) > 0) { $status = null; @@ -101,7 +100,7 @@ abstract class SpawningDaemon extends Daemon if (pcntl_wifexited($status)) { $exitCode = pcntl_wexitstatus($status); $info = "status $exitCode"; - } else if (pcntl_wifsignaled($status)) { + } elseif (pcntl_wifsignaled($status)) { $exitCode = self::EXIT_ERR; $signal = pcntl_wtermsig($status); $info = "signal $signal"; @@ -114,7 +113,7 @@ abstract class SpawningDaemon extends Daemon $pid = pcntl_fork(); if ($pid < 0) { $this->log(LOG_ERR, "Couldn't fork to respawn thread $i; aborting thread.\n"); - } else if ($pid == 0) { + } elseif ($pid === 0) { $this->initAndRunChild($i); } else { $this->log(LOG_INFO, "Respawned thread $i as pid $pid"); @@ -134,7 +133,7 @@ abstract class SpawningDaemon extends Daemon * Create an IPC socket pair which child processes can use to detect * if the parent process has been killed. */ - function initPipes() + public function initPipes() { $sockets = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, 0); if ($sockets) { @@ -197,10 +196,19 @@ abstract class SpawningDaemon extends Daemon */ protected function resetDb() { - // @fixme do we need to explicitly open the db too - // or is this implied? global $_DB_DATAOBJECT; - unset($_DB_DATAOBJECT['CONNECTIONS']); + + // Can't be called statically + $user = new User(); + $conn = $user->getDatabaseConnection(); + $conn->disconnect(); + + // Remove the disconnected connection from the list + foreach ($_DB_DATAOBJECT['CONNECTIONS'] as $k => $v) { + if ($v === $conn) { + unset($_DB_DATAOBJECT['CONNECTIONS'][$k]); + } + } // Reconnect main memcached, or threads will stomp on // each other and corrupt their requests. @@ -216,14 +224,13 @@ abstract class SpawningDaemon extends Daemon } } - function log($level, $msg) + public function log($level, $msg) { common_log($level, get_class($this) . ' ('. $this->get_id() .'): '.$msg); } - function name() + public function name() { return strtolower(get_class($this).'.'.$this->get_id()); } } -