X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=lib%2Fiomaster.php;h=1f6c31ee7e3a326ceda67b127c9890b7cba4277c;hb=914bc9f9c5ce29584e00553104ac991e6e178e7b;hp=aff5b145c219a54dcbc08697e205274ccd456193;hpb=543026b8d1411c7d71a6482d0649ab3523f489b8;p=quix0rs-gnu-social.git diff --git a/lib/iomaster.php b/lib/iomaster.php index aff5b145c2..1f6c31ee7e 100644 --- a/lib/iomaster.php +++ b/lib/iomaster.php @@ -27,7 +27,7 @@ * @link http://status.net/ */ -class IoMaster +abstract class IoMaster { public $id; @@ -38,6 +38,9 @@ class IoMaster protected $pollTimeouts = array(); protected $lastPoll = array(); + public $shutdown = false; // Did we do a graceful shutdown? + public $respawn = true; // Should we respawn after shutdown? + /** * @param string $id process ID to use in logging/monitoring */ @@ -66,23 +69,18 @@ class IoMaster if ($site != common_config('site', 'server')) { StatusNet::init($site); } - - $classes = array(); - if (Event::handle('StartIoManagerClasses', array(&$classes))) { - $classes[] = 'QueueManager'; - if (common_config('xmpp', 'enabled')) { - $classes[] = 'XmppManager'; // handles pings/reconnects - $classes[] = 'XmppConfirmManager'; // polls for outgoing confirmations - } - } - Event::handle('EndIoManagerClasses', array(&$classes)); - - foreach ($classes as $class) { - $this->instantiate($class); - } + $this->initManagers(); } } + /** + * Initialize IoManagers for the currently configured site + * which are appropriate to this instance. + * + * Pass class names into $this->instantiate() + */ + abstract function initManagers(); + /** * Pull all local sites from status_network table. * @return array of hostnames @@ -93,7 +91,7 @@ class IoMaster $sn = new Status_network(); $sn->find(); while ($sn->fetch()) { - $hosts[] = $sn->hostname; + $hosts[] = $sn->getServerName(); } return $hosts; } @@ -107,7 +105,7 @@ class IoMaster */ protected function instantiate($class) { - if (isset($this->singletons[$class])) { + if (is_string($class) && isset($this->singletons[$class])) { // Already instantiated a multi-site-capable handler. // Just let it know it should listen to this site too! $this->singletons[$class]->addSite(common_config('site', 'server')); @@ -134,7 +132,11 @@ class IoMaster protected function getManager($class) { - return call_user_func(array($class, 'get')); + if(is_object($class)){ + return $class; + } else { + return call_user_func(array($class, 'get')); + } } /** @@ -149,7 +151,7 @@ class IoMaster $this->logState('init'); $this->start(); - while (true) { + while (!$this->shutdown) { $timeouts = array_values($this->pollTimeouts); $timeouts[] = 60; // default max timeout @@ -170,7 +172,7 @@ class IoMaster $write = array(); $except = array(); $this->logState('listening'); - common_log(LOG_INFO, "Waiting up to $timeout seconds for socket data..."); + common_log(LOG_DEBUG, "Waiting up to $timeout seconds for socket data..."); $ready = stream_select($read, $write, $except, $timeout, 0); if ($ready === false) { @@ -190,7 +192,7 @@ class IoMaster if ($timeout > 0 && empty($sockets)) { // If we had no listeners, sleep until the pollers' next requested wakeup. - common_log(LOG_INFO, "Sleeping $timeout seconds until next poll cycle..."); + common_log(LOG_DEBUG, "Sleeping $timeout seconds until next poll cycle..."); $this->logState('sleep'); sleep($timeout); } @@ -201,20 +203,31 @@ class IoMaster $this->logState('idle'); $this->idle(); - $memoryLimit = $this->softMemoryLimit(); - if ($memoryLimit > 0) { - $usage = memory_get_usage(); - if ($usage > $memoryLimit) { - common_log(LOG_INFO, "Queue thread hit soft memory limit ($usage > $memoryLimit); gracefully restarting."); - break; - } - } + $this->checkMemory(); } $this->logState('shutdown'); $this->finish(); } + /** + * Check runtime memory usage, possibly triggering a graceful shutdown + * and thread respawn if we've crossed the soft limit. + */ + protected function checkMemory() + { + $memoryLimit = $this->softMemoryLimit(); + if ($memoryLimit > 0) { + $usage = memory_get_usage(); + if ($usage > $memoryLimit) { + common_log(LOG_INFO, "Queue thread hit soft memory limit ($usage > $memoryLimit); gracefully restarting."); + $this->requestRestart(); + } else if (common_config('queue', 'debug_memory')) { + common_log(LOG_DEBUG, "Memory usage $usage"); + } + } + } + /** * Return fully-parsed soft memory limit in bytes. * @return intval 0 or -1 if not set @@ -223,15 +236,14 @@ class IoMaster { $softLimit = trim(common_config('queue', 'softlimit')); if (substr($softLimit, -1) == '%') { - $limit = trim(ini_get('memory_limit')); - $limit = $this->parseMemoryLimit($limit); + $limit = $this->parseMemoryLimit(ini_get('memory_limit')); if ($limit > 0) { return intval(substr($softLimit, 0, -1) * $limit / 100); } else { return -1; } } else { - return $this->parseMemoryLimit($limit); + return $this->parseMemoryLimit($softLimit); } return $softLimit; } @@ -242,9 +254,10 @@ class IoMaster * @param string $mem * @return int */ - protected function parseMemoryLimit($mem) + public function parseMemoryLimit($mem) { // http://www.php.net/manual/en/faq.using.php#faq.using.shorthandbytes + $mem = strtolower(trim($mem)); $size = array('k' => 1024, 'm' => 1024*1024, 'g' => 1024*1024*1024); @@ -253,7 +266,7 @@ class IoMaster } else if (is_numeric($mem)) { return intval($mem); } else { - $mult = strtolower(substr($mem, -1)); + $mult = substr($mem, -1); if (isset($size[$mult])) { return substr($mem, 0, -1) * $size[$mult]; } else { @@ -350,12 +363,31 @@ class IoMaster * for per-queue and per-site records. * * @param string $key counter name - * @param array $owners list of owner keys like 'queue:jabber' or 'site:stat01' + * @param array $owners list of owner keys like 'queue:xmpp' or 'site:stat01' */ public function stats($key, $owners=array()) { $owners[] = "thread:" . $this->id; $this->monitor->stats($key, $owners); } + + /** + * For IoManagers to request a graceful shutdown at end of event loop. + */ + public function requestShutdown() + { + $this->shutdown = true; + $this->respawn = false; + } + + /** + * For IoManagers to request a graceful restart at end of event loop. + */ + public function requestRestart() + { + $this->shutdown = true; + $this->respawn = true; + } + }