From e7ab305335dd826211cf9548b0cd04ec376862f5 Mon Sep 17 00:00:00 2001 From: Alexei Sorokin Date: Tue, 7 Jan 2020 19:48:13 +0300 Subject: [PATCH] [CORE] Use monotonic time via hrtime() where applicable The realtime clock is not reliable when calculating elapsed time. --- classes/Memcached_DataObject.php | 6 +- lib/action/action.php | 8 +- lib/notices/jsonsearchresultslist.php | 121 +++++----- lib/util/iomaster.php | 67 +++--- lib/util/util.php | 10 +- plugins/Cronish/lib/cronish.php | 33 ++- plugins/Geonames/GeonamesPlugin.php | 208 ++++++++++-------- plugins/OStatus/tests/gettext-speedtest.php | 58 ++--- .../lib/opportunisticqueuemanager.php | 43 +++- plugins/SQLStats/SQLStatsPlugin.php | 69 +++--- public/index.php | 31 ++- 11 files changed, 364 insertions(+), 290 deletions(-) diff --git a/classes/Memcached_DataObject.php b/classes/Memcached_DataObject.php index 2784701130..2d1f7946a1 100644 --- a/classes/Memcached_DataObject.php +++ b/classes/Memcached_DataObject.php @@ -665,7 +665,7 @@ class Memcached_DataObject extends Safe_DataObject $string = $this->annotateQuery($string); } - $start = microtime(true); + $start = hrtime(true); $fail = false; $result = null; if (Event::handle('StartDBQuery', array($this, $string, &$result))) { @@ -677,7 +677,7 @@ class Memcached_DataObject extends Safe_DataObject } Event::handle('EndDBQuery', array($this, $string, &$result)); } - $delta = microtime(true) - $start; + $delta = (hrtime(true) - $start) / 1000000000; $limit = common_config('db', 'log_slow_queries'); if (($limit > 0 && $delta >= $limit) || common_config('db', 'log_queries')) { @@ -978,7 +978,7 @@ class Memcached_DataObject extends Safe_DataObject $vstr = ''; break; } - // fallthrough + // no break case 'blob': case 'string': case 'datetime': diff --git a/lib/action/action.php b/lib/action/action.php index a768264357..bcac975a4c 100644 --- a/lib/action/action.php +++ b/lib/action/action.php @@ -600,11 +600,11 @@ class Action extends HTMLOutputter // lawsuit public function endHTML() { - global $_startTime; + global $_startCpuTime; - if (isset($_startTime)) { - $endTime = microtime(true); - $diff = round(($endTime - $_startTime) * 1000); + if (isset($_startCpuTime)) { + $end_cpu_time = hrtime(true); + $diff = round(($end_cpu_time - $_startCpuTime) / 1000000); $this->raw(""); } diff --git a/lib/notices/jsonsearchresultslist.php b/lib/notices/jsonsearchresultslist.php index 80dc33e323..b16051c839 100644 --- a/lib/notices/jsonsearchresultslist.php +++ b/lib/notices/jsonsearchresultslist.php @@ -1,44 +1,38 @@ . + /** - * StatusNet, the distributed open-source microblogging tool - * - * widget for displaying a list of notices - * - * PHP version 5 - * - * LICENCE: This program 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. - * - * This program 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 this program. If not, see . + * Widget for displaying a list of notices. * * @category Search - * @package StatusNet + * @package GNUsocial * @author Zach Copley * @copyright 2009 StatusNet, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://status.net/ + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ -if (!defined('STATUSNET') && !defined('LACONICA')) { - exit(1); -} +defined('GNUSOCIAL') || die(); /** - * widget-like class for showing JSON search results + * Widget-like class for showing JSON search results. * - * @category Search - * @package StatusNet - * @author Zach Copley - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://status.net/ + * @category Search + * @package GNUsocial + * @author Zach Copley + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * */ @@ -50,14 +44,14 @@ class JSONSearchResultsList // The below attributes are carefully named so the JSON output from // this obj matches the output from search.twitter.com - var $results; - var $since_id; - var $max_id; - var $refresh_url; - var $results_per_page; - var $completed_in; - var $page; - var $query; + public $results; + public $since_id; + public $max_id; + public $refresh_url; + public $results_per_page; + public $completed_in; + public $page; + public $query; /** * constructor @@ -69,7 +63,7 @@ class JSONSearchResultsList * @param int $since_id only display notices newer than this */ - function __construct($notice, $query, $rpp, $page, $since_id = 0) + public function __construct($notice, $query, $rpp, $page, $since_id = 0) { $this->notice = $notice; $this->query = urlencode($query); @@ -86,12 +80,12 @@ class JSONSearchResultsList * @return int $count of the search results listed. */ - function show() + public function show() { $cnt = 0; $this->max_id = 0; - $time_start = microtime(true); + $time_start = hrtime(true); while ($this->notice->fetch() && $cnt <= $this->rpp) { $cnt++; @@ -119,8 +113,8 @@ class JSONSearchResultsList } } - $time_end = microtime(true); - $this->completed_in = $time_end - $time_start; + $time_end = hrtime(true); + $this->completed_in = ($time_end - $time_start) / 1000000000; // Set other attrs @@ -154,14 +148,13 @@ class JSONSearchResultsList } /** - * widget for displaying a single JSON search result + * Widget for displaying a single JSON search result. * - * @category UI - * @package StatusNet - * @author Zach Copley - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://status.net/ - * @see JSONSearchResultsList + * @category UI + * @package GNUsocial + * @author Zach Copley + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later + * @see JSONSearchResultsList */ class ResultItem @@ -177,17 +170,17 @@ class ResultItem // The below attributes are carefully named so the JSON output from // this obj matches the output from search.twitter.com - var $text; - var $to_user_id; - var $to_user; - var $from_user; - var $id; - var $from_user_id; - var $iso_language_code; - var $source = null; - var $source_link = null; - var $profile_image_url; - var $created_at; + public $text; + public $to_user_id; + public $to_user; + public $from_user; + public $id; + public $from_user_id; + public $iso_language_code; + public $source = null; + public $source_link = null; + public $profile_image_url; + public $created_at; /** * constructor @@ -197,7 +190,7 @@ class ResultItem * @param Notice $notice The notice we'll display */ - function __construct($notice) + public function __construct($notice) { $this->notice = $notice; $this->profile = $notice->getProfile(); @@ -212,7 +205,7 @@ class ResultItem * @return void */ - function buildResult() + public function buildResult() { $this->text = $this->notice->content; $replier_profile = null; @@ -251,7 +244,7 @@ class ResultItem * * @return void */ - function setSourceData() + public function setSourceData() { $source = null; $source_link = null; diff --git a/lib/util/iomaster.php b/lib/util/iomaster.php index 7072761f2d..d47e66a21d 100644 --- a/lib/util/iomaster.php +++ b/lib/util/iomaster.php @@ -1,32 +1,31 @@ . + /** - * StatusNet, the distributed open-source microblogging tool - * * I/O manager to wrap around socket-reading and polling queue & connection managers. * - * PHP version 5 - * - * LICENCE: This program 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. - * - * This program 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 this program. If not, see . - * * @category QueueManager - * @package StatusNet + * @package GNUsocial * @author Brion Vibber * @copyright 2009 StatusNet, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://status.net/ + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ +defined('GNUSOCIAL') || die(); + abstract class IoMaster { public $id; @@ -68,7 +67,7 @@ abstract class IoMaster * * Switching site configurations is an acceptable side effect. */ - abstract function initManagers(); + abstract public function initManagers(); /** * Instantiate an i/o manager class for the current site. @@ -88,7 +87,7 @@ abstract class IoMaster if ($this->multiSite) { throw new Exception("$class can't run with --all; aborting."); } - } else if ($caps == IoManager::INSTANCE_PER_PROCESS) { + } elseif ($caps == IoManager::INSTANCE_PER_PROCESS) { $manager->addSite(); } @@ -105,7 +104,7 @@ abstract class IoMaster * Between events or timeouts, pass control back to idle() method * to allow for any additional background processing. */ - function service() + public function service() { $this->logState('init'); $this->start(); @@ -137,7 +136,7 @@ abstract class IoMaster if ($ready === false) { common_log(LOG_ERR, "Error selecting on sockets"); - } else if ($ready > 0) { + } elseif ($ready > 0) { foreach ($read as $socket) { $index = array_search($socket, $sockets, true); if ($index !== false) { @@ -188,7 +187,7 @@ abstract class IoMaster } else { $this->requestShutdown(); } - } else if (common_config('queue', 'debug_memory')) { + } elseif (common_config('queue', 'debug_memory')) { $fmt = number_format($usage); common_log(LOG_DEBUG, "Memory usage $fmt"); } @@ -199,7 +198,7 @@ abstract class IoMaster * Return fully-parsed soft memory limit in bytes. * @return intval 0 or -1 if not set */ - function softMemoryLimit() + public function softMemoryLimit() { $softLimit = trim(common_config('queue', 'softlimit')); if (substr($softLimit, -1) == '%') { @@ -230,7 +229,7 @@ abstract class IoMaster 'g' => 1024*1024*1024); if (empty($mem)) { return 0; - } else if (is_numeric($mem)) { + } elseif (is_numeric($mem)) { return intval($mem); } else { $mult = substr($mem, -1); @@ -242,7 +241,7 @@ abstract class IoMaster } } - function start() + public function start() { foreach ($this->managers as $index => $manager) { $manager->start($this); @@ -255,7 +254,7 @@ abstract class IoMaster } } - function finish() + public function finish() { foreach ($this->managers as $manager) { $manager->finish(); @@ -266,7 +265,7 @@ abstract class IoMaster /** * Called during the idle portion of the runloop to see which handlers */ - function poll() + public function poll() { foreach ($this->managers as $index => $manager) { $interval = $manager->pollInterval(); @@ -277,7 +276,7 @@ abstract class IoMaster if (isset($this->pollTimeouts[$index])) { $timeout = $this->pollTimeouts[$index]; - if (time() - $this->lastPoll[$index] < $timeout) { + if (hrtime(true) - $this->lastPoll[$index] < $timeout * 1000000000) { // Not time to poll yet. continue; } @@ -286,7 +285,7 @@ abstract class IoMaster } $hit = $manager->poll(); - $this->lastPoll[$index] = time(); + $this->lastPoll[$index] = hrtime(true); if ($hit) { // Do the next poll quickly, there may be more input! $this->pollTimeouts[$index] = 0; @@ -306,7 +305,7 @@ abstract class IoMaster * Called after each handled item or empty polling cycle. * This is a good time to e.g. service your XMPP connection. */ - function idle() + public function idle() { foreach ($this->managers as $manager) { $manager->idle(); @@ -355,6 +354,4 @@ abstract class IoMaster $this->shutdown = true; $this->respawn = true; } - } - diff --git a/lib/util/util.php b/lib/util/util.php index fb631bb68d..831ad86433 100644 --- a/lib/util/util.php +++ b/lib/util/util.php @@ -2331,7 +2331,7 @@ function common_profile_uri($profile) if ($user instanceof User) { $uri = $user->getUri(); } // FIXME: might be a remote profile, by this function name, I would guess it would be fine to call this - // On the other hand, there's Profile->getUri + // On the other hand, there's Profile->getUri Event::handle('EndCommonProfileURI', [$profile, &$uri]); } } @@ -2606,11 +2606,11 @@ function common_perf_counter($key, $val=null) function common_log_perf_counters() { if (common_config('site', 'logperf')) { - global $_startTime, $_perfCounters; + global $_startCpuTime, $_perfCounters; - if (isset($_startTime)) { - $endTime = microtime(true); - $diff = round(($endTime - $_startTime) * 1000); + if (isset($_startCpuTime)) { + $end_cpu_time = hrtime(true); + $diff = round(($end_cpu_time - $_startCpuTime) / 1000000); common_log(LOG_DEBUG, "PERF runtime: ${diff}ms"); } $counters = $_perfCounters; diff --git a/plugins/Cronish/lib/cronish.php b/plugins/Cronish/lib/cronish.php index 5889b079f4..f13266d7a5 100644 --- a/plugins/Cronish/lib/cronish.php +++ b/plugins/Cronish/lib/cronish.php @@ -1,17 +1,34 @@ . + /** * GNU social cron-on-visit class * - * Keeps track, through Config dataobject class, of relative time since the + * Keeps track, through Config dataobject class, of relative time since the * last run in order to to run event handlers with certain intervals. * * @category Cron * @package GNUsocial * @author Mikael Nordfeldth - * @copyright 2013 Free Software Foundation, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 - * @link http://status.net/ + * @copyright 2013 Free Software Foundation, Inc http://www.fsf.or + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ + +defined('GNUSOCIAL') || die(); + class Cronish { /** @@ -28,7 +45,7 @@ class Cronish 'daily' => 86400, 'weekly' => 604800); - foreach($timers as $name=>$interval) { + foreach ($timers as $name => $interval) { $run = false; $lastrun = new Config(); @@ -37,15 +54,15 @@ class Cronish $found = $lastrun->find(true); if (!$found) { - $lastrun->value = time(); + $lastrun->value = hrtime(true); if ($lastrun->insert() === false) { common_log(LOG_WARNING, "Could not save 'cron' setting '{$name}'"); continue; } $run = true; - } elseif ($lastrun->value < time() - $interval) { + } elseif ($lastrun->value < hrtime(true) - $interval * 1000000000) { $orig = clone($lastrun); - $lastrun->value = time(); + $lastrun->value = hrtime(true); $lastrun->update($orig); $run = true; } diff --git a/plugins/Geonames/GeonamesPlugin.php b/plugins/Geonames/GeonamesPlugin.php index 33ea9d51c1..c178ce807e 100644 --- a/plugins/Geonames/GeonamesPlugin.php +++ b/plugins/Geonames/GeonamesPlugin.php @@ -1,50 +1,44 @@ . + /** - * StatusNet, the distributed open-source microblogging tool - * - * Plugin to convert string locations to Geonames IDs and vice versa - * - * PHP version 5 - * - * LICENCE: This program 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. - * - * This program 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 this program. If not, see . + * Plugin to convert string locations to Geonames IDs and vice versa. * * @category Action - * @package StatusNet + * @package GNUsocial * @author Evan Prodromou * @copyright 2009 StatusNet Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://status.net/ + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ -if (!defined('STATUSNET')) { - exit(1); -} +defined('GNUSOCIAL') || die(); /** - * Plugin to convert string locations to Geonames IDs and vice versa + * Plugin to convert string locations to Geonames IDs and vice versa. * * This handles most of the events that Location class emits. It uses * the geonames.org Web service to convert names like 'Montreal, Quebec, Canada' * into IDs and lat/lon pairs. * - * @category Plugin - * @package StatusNet - * @author Evan Prodromou - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://status.net/ + * @category Plugin + * @package GNUsocial + * @author Evan Prodromou + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later * - * @seeAlso Location + * @seeAlso Location */ class GeonamesPlugin extends Plugin { @@ -61,7 +55,7 @@ class GeonamesPlugin extends Plugin public $cachePrefix = null; // Optional shared memcache prefix override // to share lookups between local instances. - protected $lastTimeout = null; // timestamp of last web service timeout + protected $lastTimeout = null; // CPU time of last web service timeout /** * convert a name into a Location object @@ -72,10 +66,12 @@ class GeonamesPlugin extends Plugin * * @return boolean whether to continue (results in $location) */ - function onLocationFromName($name, $language, &$location) + public function onLocationFromName($name, $language, &$location) { - $loc = $this->getCache(array('name' => $name, - 'language' => $language)); + $loc = $this->getCache([ + 'name' => $name, + 'language' => $language, + ]); if ($loc !== false) { $location = $loc; @@ -83,11 +79,15 @@ class GeonamesPlugin extends Plugin } try { - $geonames = $this->getGeonames('search', - array('maxRows' => 1, - 'q' => $name, - 'lang' => $language, - 'type' => 'xml')); + $geonames = $this->getGeonames( + 'search', + [ + 'maxRows' => 1, + 'q' => $name, + 'lang' => $language, + 'type' => 'xml', + ] + ); } catch (Exception $e) { $this->log(LOG_WARNING, "Error for $name: " . $e->getMessage()); return true; @@ -95,9 +95,13 @@ class GeonamesPlugin extends Plugin if (count($geonames) == 0) { // no results - $this->setCache(array('name' => $name, - 'language' => $language), - null); + $this->setCache( + [ + 'name' => $name, + 'language' => $language, + ], + null + ); return true; } @@ -111,9 +115,13 @@ class GeonamesPlugin extends Plugin $location->location_id = (string)$n->geonameId; $location->location_ns = self::LOCATION_NS; - $this->setCache(array('name' => $name, - 'language' => $language), - $location); + $this->setCache( + [ + 'name' => $name, + 'language' => $language, + ], + $location + ); // handled, don't continue processing! return false; @@ -129,7 +137,7 @@ class GeonamesPlugin extends Plugin * * @return boolean whether to continue (results in $location) */ - function onLocationFromId($id, $ns, $language, &$location) + public function onLocationFromId($id, $ns, $language, &$location) { if ($ns != self::LOCATION_NS) { // It's not one of our IDs... keep processing @@ -144,9 +152,13 @@ class GeonamesPlugin extends Plugin } try { - $geonames = $this->getGeonames('hierarchy', - array('geonameId' => $id, - 'lang' => $language)); + $geonames = $this->getGeonames( + 'hierarchy', + [ + 'geonameId' => $id, + 'lang' => $language, + ] + ); } catch (Exception $e) { $this->log(LOG_WARNING, "Error for ID $id: " . $e->getMessage()); return false; @@ -175,8 +187,10 @@ class GeonamesPlugin extends Plugin $location->names[$language] = implode(', ', array_reverse($parts)); - $this->setCache(array('id' => (string)$last->geonameId), - $location); + $this->setCache( + ['id' => (string) $last->geonameId], + $location + ); // We're responsible for this namespace; nobody else // can resolve it @@ -197,15 +211,14 @@ class GeonamesPlugin extends Plugin * * @return boolean whether to continue (results in $location) */ - function onLocationFromLatLon($lat, $lon, $language, &$location) + public function onLocationFromLatLon($lat, $lon, $language, &$location) { // Make sure they're canonical $lat = $this->canonical($lat); $lon = $this->canonical($lon); - $loc = $this->getCache(array('lat' => $lat, - 'lon' => $lon)); + $loc = $this->getCache(['lat' => $lat, 'lon' => $lon]); if ($loc !== false) { $location = $loc; @@ -213,10 +226,14 @@ class GeonamesPlugin extends Plugin } try { - $geonames = $this->getGeonames('findNearbyPlaceName', - array('lat' => $lat, - 'lng' => $lon, - 'lang' => $language)); + $geonames = $this->getGeonames( + 'findNearbyPlaceName', + [ + 'lat' => $lat, + 'lng' => $lon, + 'lang' => $language, + ] + ); } catch (Exception $e) { $this->log(LOG_WARNING, "Error for coords $lat, $lon: " . $e->getMessage()); return true; @@ -224,9 +241,10 @@ class GeonamesPlugin extends Plugin if (count($geonames) == 0) { // no results - $this->setCache(array('lat' => $lat, - 'lon' => $lon), - null); + $this->setCache( + ['lat' => $lat, 'lon' => $lon], + null + ); return true; } @@ -253,9 +271,10 @@ class GeonamesPlugin extends Plugin $location->names[$language] = implode(', ', $parts); - $this->setCache(array('lat' => $lat, - 'lon' => $lon), - $location); + $this->setCache( + ['lat' => $lat, 'lon' => $lon], + $location + ); // Success! We handled it, so no further processing @@ -274,7 +293,7 @@ class GeonamesPlugin extends Plugin * * @return boolean whether to continue */ - function onLocationNameLanguage($location, $language, &$name) + public function onLocationNameLanguage($location, $language, &$name) { if ($location->location_ns != self::LOCATION_NS) { // It's not one of our IDs... keep processing @@ -292,18 +311,26 @@ class GeonamesPlugin extends Plugin } try { - $geonames = $this->getGeonames('hierarchy', - array('geonameId' => $id, - 'lang' => $language)); + $geonames = $this->getGeonames( + 'hierarchy', + [ + 'geonameId' => $id, + 'lang' => $language, + ] + ); } catch (Exception $e) { $this->log(LOG_WARNING, "Error for ID $id: " . $e->getMessage()); return false; } if (count($geonames) == 0) { - $this->setCache(array('id' => $id, - 'language' => $language), - null); + $this->setCache( + [ + 'id' => $id, + 'language' => $language, + ], + null + ); return false; } @@ -323,9 +350,13 @@ class GeonamesPlugin extends Plugin if (count($parts)) { $name = implode(', ', array_reverse($parts)); - $this->setCache(array('id' => $id, - 'language' => $language), - $name); + $this->setCache( + [ + 'id' => $id, + 'language' => $language, + ], + $name + ); } return false; @@ -341,7 +372,7 @@ class GeonamesPlugin extends Plugin * * @return boolean whether to continue */ - function onLocationUrl($location, &$url) + public function onLocationUrl($location, &$url) { if ($location->location_ns != self::LOCATION_NS) { // It's not one of our IDs... keep processing @@ -364,7 +395,7 @@ class GeonamesPlugin extends Plugin * * @return boolean whether to continue */ - function onLocationRdfUrl($location, &$url) + public function onLocationRdfUrl($location, &$url) { if ($location->location_ns != self::LOCATION_NS) { // It's not one of our IDs... keep processing @@ -377,7 +408,7 @@ class GeonamesPlugin extends Plugin return false; } - function getCache($attrs) + public function getCache($attrs) { $c = Cache::instance(); @@ -392,7 +423,7 @@ class GeonamesPlugin extends Plugin return $value; } - function setCache($attrs, $loc) + public function setCache($attrs, $loc) { $c = Cache::instance(); @@ -407,7 +438,7 @@ class GeonamesPlugin extends Plugin return $result; } - function cacheKey($attrs) + public function cacheKey($attrs) { $key = 'geonames:' . implode(',', array_keys($attrs)) . ':'. @@ -419,7 +450,7 @@ class GeonamesPlugin extends Plugin } } - function wsUrl($method, $params) + public function wsUrl($method, $params) { if (!empty($this->username)) { $params['username'] = $this->username; @@ -431,12 +462,13 @@ class GeonamesPlugin extends Plugin $str = http_build_query($params, null, '&'); - return 'http://'.$this->host.'/'.$method.'?'.$str; + return "http://{$this->host}/{$method}?{$str}"; } - function getGeonames($method, $params) + public function getGeonames($method, $params) { - if ($this->lastTimeout && (time() - $this->lastTimeout < $this->timeoutWindow)) { + if (!is_null($this->lastTimeout) + && (hrtime(true) - $this->lastTimeout < $this->timeoutWindow * 1000000000)) { // TRANS: Exception thrown when a geo names service is not used because of a recent timeout. throw new Exception(_m('Skipping due to recent web service timeout.')); } @@ -449,14 +481,14 @@ class GeonamesPlugin extends Plugin $result = $client->get($this->wsUrl($method, $params)); } catch (Exception $e) { common_log(LOG_ERR, __METHOD__ . ": " . $e->getMessage()); - $this->lastTimeout = time(); + $this->lastTimeout = hrtime(true); throw $e; } if (!$result->isOk()) { // TRANS: Exception thrown when a geo names service does not return an expected response. // TRANS: %s is an HTTP error code. - throw new Exception(sprintf(_m('HTTP error code %s.'),$result->getStatus())); + throw new Exception(sprintf(_m('HTTP error code %s.'), $result->getStatus())); } $body = $result->getBody(); @@ -481,7 +513,7 @@ class GeonamesPlugin extends Plugin if (isset($document->status)) { // TRANS: Exception thrown when a geo names service return a specific error number and error text. // TRANS: %1$s is an error code, %2$s is an error message. - throw new Exception(sprintf(_m('Error #%1$s ("%2$s").'),$document->status['value'],$document->status['message'])); + throw new Exception(sprintf(_m('Error #%1$s ("%2$s").'), $document->status['value'], $document->status['message'])); } // Array of elements, >0 elements @@ -502,7 +534,7 @@ class GeonamesPlugin extends Plugin return true; } - function canonical($coord) + public function canonical($coord) { $coord = rtrim($coord, "0"); $coord = rtrim($coord, "."); diff --git a/plugins/OStatus/tests/gettext-speedtest.php b/plugins/OStatus/tests/gettext-speedtest.php index 0584af8ef4..a7e38f8a95 100644 --- a/plugins/OStatus/tests/gettext-speedtest.php +++ b/plugins/OStatus/tests/gettext-speedtest.php @@ -25,55 +25,55 @@ _bindtextdomain("statusnet", INSTALLDIR . '/locale'); _bindtextdomain("FeedSub", INSTALLDIR . '/plugins/FeedSub/locale'); $times = 10000; -$delta = array(); +$delta = []; -$start = microtime(true); -for($i = 0; $i < $times; $i++) { - $result = _("Send"); +$start = hrtime(true); +for ($i = 0; $i < $times; ++$i) { + $result = _('Send'); } -$delta["_"] = array((microtime(true) - $start) / $times, $result); +$delta['_'] = [(hrtime(true) - $start) / $times, $result]; -$start = microtime(true); -for($i = 0; $i < $times; $i++) { - $result = __("Send"); +$start = hrtime(true); +for ($i = 0; $i < $times; ++$i) { + $result = __('Send'); } -$delta["__"] = array((microtime(true) - $start) / $times, $result); +$delta['__'] = [(hrtime(true) - $start) / $times, $result]; -$start = microtime(true); -for($i = 0; $i < $times; $i++) { - $result = dgettext("FeedSub", "Feeds"); +$start = hrtime(true); +for ($i = 0; $i < $times; ++$i) { + $result = dgettext('FeedSub', 'Feeds'); } -$delta["dgettext"] = array((microtime(true) - $start) / $times, $result); +$delta['dgettext'] = [(hrtime(true) - $start) / $times, $result]; -$start = microtime(true); -for($i = 0; $i < $times; $i++) { - $result = _dgettext("FeedSub", "Feeds"); +$start = hrtime(true); +for ($i = 0; $i < $times; ++$i) { + $result = _dgettext('FeedSub', 'Feeds'); } -$delta["_dgettext"] = array((microtime(true) - $start) / $times, $result); +$delta['_dgettext'] = [(hrtime(true) - $start) / $times, $result]; -$start = microtime(true); -for($i = 0; $i < $times; $i++) { +$start = hrtime(true); +for ($i = 0; $i < $times; ++$i) { // TRANS: String in the gettext speed test script. Unimportant. - $result = _m("Feeds"); + $result = _m('Feeds'); } -$delta["_m"] = array((microtime(true) - $start) / $times, $result); +$delta['_m'] = [(hrtime(true) - $start) / $times, $result]; -$start = microtime(true); -for($i = 0; $i < $times; $i++) { - $result = fake("Feeds"); +$start = hrtime(true); +for ($i = 0; $i < $times; ++$i) { + $result = fake('Feeds'); } -$delta["fake"] = array((microtime(true) - $start) / $times, $result); +$delta['fake'] = [(hrtime(true) - $start) / $times, $result]; foreach ($delta as $func => $bits) { - list($time, $result) = $bits; - $ms = $time * 1000.0; + [$time, $result] = $bits; + $ms = $time / 1000000; printf("%10s %2.4fms %s\n", $func, $ms, $result); } -function fake($str) { +function fake(string $str) +{ return $str; } - diff --git a/plugins/OpportunisticQM/lib/opportunisticqueuemanager.php b/plugins/OpportunisticQM/lib/opportunisticqueuemanager.php index 520cc52af2..2d10b8e95b 100644 --- a/plugins/OpportunisticQM/lib/opportunisticqueuemanager.php +++ b/plugins/OpportunisticQM/lib/opportunisticqueuemanager.php @@ -1,4 +1,19 @@ . + /** * GNU social queue-manager-on-visit class * @@ -10,10 +25,12 @@ * @category Cron * @package GNUsocial * @author Mikael Nordfeldth - * @copyright 2013 Free Software Foundation, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 - * @link http://status.net/ + * @copyright 2013 Free Software Foundation, Inc http://www.fsf.org + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ + +defined('GNUSOCIAL') || die(); + class OpportunisticQueueManager extends QueueManager { protected $qmkey = false; @@ -21,7 +38,7 @@ class OpportunisticQueueManager extends QueueManager protected $max_execution_margin = null; // margin to PHP's max_execution_time protected $max_queue_items = null; - protected $started_at = null; + protected $start_cpu_time = null; protected $handled_items = 0; protected $verbosity = null; @@ -29,7 +46,8 @@ class OpportunisticQueueManager extends QueueManager // typically just used for the /main/cron action, only used if php.ini max_execution_time is 0 const MAXEXECTIME = 20; - public function __construct(array $args = []) { + public function __construct(array $args = []) + { foreach (get_class_vars(get_class($this)) as $key=>$val) { if (array_key_exists($key, $args)) { $this->$key = $args[$key]; @@ -37,15 +55,15 @@ class OpportunisticQueueManager extends QueueManager } $this->verifyKey(); - if ($this->started_at === null) { - $this->started_at = time(); + if (is_null($this->start_cpu_time)) { + $this->start_cpu_time = hrtime(true); } - if ($this->max_execution_time === null) { + if (is_null($this->max_execution_time)) { $this->max_execution_time = ini_get('max_execution_time') ?: self::MAXEXECTIME; } - if ($this->max_execution_margin === null) { + if (is_null($this->max_execution_margin)) { // think PHP's max exec time, minus this value to have time for timeouts etc. $this->max_execution_margin = common_config('http', 'connect_timeout') + 1; } @@ -69,7 +87,7 @@ class OpportunisticQueueManager extends QueueManager public function canContinue() { - $time_passed = time() - $this->started_at; + $time_passed = (hrtime(true) - $this->start_cpu_time) / 1000000000; // Only continue if limit values are sane if ($time_passed <= 0 && (!is_null($this->max_queue_items) && $this->max_queue_items <= 0)) { @@ -121,9 +139,10 @@ class OpportunisticQueueManager extends QueueManager 'handling limit without being out of work.'); return true; } elseif ($this->verbosity > 1) { + $time_passed = (hrtime(true) - $this->start_cpu_time) / 1000000000; common_debug('Opportunistic queue manager did not have time to start ' . - 'on this action (max: ' . $this->max_execution_time . - ' exceeded: ' . abs(time() - $this->started_at) . ').'); + "on this action (max: {$this->max_execution_time}" . + " exceeded: {$time_passed})."); } return false; diff --git a/plugins/SQLStats/SQLStatsPlugin.php b/plugins/SQLStats/SQLStatsPlugin.php index 20c74b5404..6975bd053d 100644 --- a/plugins/SQLStats/SQLStatsPlugin.php +++ b/plugins/SQLStats/SQLStatsPlugin.php @@ -1,31 +1,36 @@ . + /* - * StatusNet - the distributed open-source microblogging tool - * Copyright (C) 2011, StatusNet, Inc. + * Check DB queries for filesorts and such and log em. * - * This program 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. - * - * This program 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 this program. If not, see . + * @package SQLStatsPlugin + * @author Evan Prodromou + * @copyright 2011 StatusNet, Inc. + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ -if (!defined('STATUSNET')) { - exit(1); -} +defined('GNUSOCIAL') || die(); /** * Check DB queries for filesorts and such and log em. * - * @package SQLStatsPlugin - * @maintainer Evan Prodromou + * @package SQLStatsPlugin + * @author Evan Prodromou + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ class SQLStatsPlugin extends Plugin { @@ -49,33 +54,35 @@ class SQLStatsPlugin extends Plugin return true; } - function onStartDBQuery($obj, $query, &$result) + public function onStartDBQuery($obj, $query, &$result) { - $this->queryStart = microtime(true); + $this->queryStart = hrtime(true); return true; } - function onEndDBQuery($obj, $query, &$result) + public function onEndDBQuery($obj, $query, &$result) { - $endTime = microtime(true); - $this->queryTimes[] = round(($endTime - $this->queryStart) * 1000); + $endTime = hrtime(true); + $this->queryTimes[] = round(($endTime - $this->queryStart) / 1000000); $this->queries[] = trim(preg_replace('/\s/', ' ', $query)); $this->queryStart = 0; return true; } - function cleanup() + public function cleanup() { if (count($this->queryTimes) == 0) { $this->log(LOG_INFO, sprintf('0 queries this hit.')); } else { - $this->log(LOG_INFO, sprintf('%d queries this hit (total = %d, avg = %d, max = %d, min = %d)', - count($this->queryTimes), - array_sum($this->queryTimes), - array_sum($this->queryTimes)/count($this->queryTimes), - max($this->queryTimes), - min($this->queryTimes))); + $this->log(LOG_INFO, sprintf( + '%d queries this hit (total = %d, avg = %d, max = %d, min = %d)', + count($this->queryTimes), + array_sum($this->queryTimes), + array_sum($this->queryTimes) / count($this->queryTimes), + max($this->queryTimes), + min($this->queryTimes) + )); } $verbose = common_config('sqlstats', 'verbose'); diff --git a/public/index.php b/public/index.php index 59eac50755..30d584c732 100644 --- a/public/index.php +++ b/public/index.php @@ -48,7 +48,8 @@ */ $_startTime = microtime(true); -$_perfCounters = array(); +$_startCpuTime = hrtime(true); +$_perfCounters = []; // We provide all our dependencies through our own autoload. // This will probably be configurable for distributing with @@ -72,7 +73,7 @@ function getPath($req) && array_key_exists('p', $req) ) { $p = $req['p']; - } else if (array_key_exists('PATH_INFO', $_SERVER)) { + } elseif (array_key_exists('PATH_INFO', $_SERVER)) { $path = $_SERVER['PATH_INFO']; $script = $_SERVER['SCRIPT_NAME']; if (substr($path, 0, mb_strlen($script)) == $script) { @@ -99,7 +100,6 @@ function getPath($req) function handleError($error) { try { - if ($error->getCode() == DB_DATAOBJECT_ERROR_NODATA) { return; } @@ -152,7 +152,6 @@ function handleError($error) $erraction = new ServerErrorAction($error->getMessage(), 500, $error); } $erraction->showPage(); - } catch (Exception $e) { // TRANS: Error message. echo _('An error occurred.'); @@ -182,12 +181,18 @@ require_once INSTALLDIR . '/lib/util/common.php'; function formatBacktraceLine($n, $line) { $out = "#$n "; - if (isset($line['class'])) $out .= $line['class']; - if (isset($line['type'])) $out .= $line['type']; - if (isset($line['function'])) $out .= $line['function']; + if (array_key_exists('class', $line)) { + $out .= $line['class']; + } + if (array_key_exists('type', $line)) { + $out .= $line['type']; + } + if (array_key_exists('function', $line)) { + $out .= $line['function']; + } $out .= '('; - if (isset($line['args'])) { - $args = array(); + if (array_key_exists('args', $line)) { + $args = []; foreach ($line['args'] as $arg) { // debug_print_backtrace seems to use var_export // but this gets *very* verbose! @@ -197,8 +202,12 @@ function formatBacktraceLine($n, $line) } $out .= ')'; $out .= ' called at ['; - if (isset($line['file'])) $out .= $line['file']; - if (isset($line['line'])) $out .= ':' . $line['line']; + if (array_key_exists('file', $line)) { + $out .= $line['file']; + } + if (array_key_exists('line', $line)) { + $out .= ':' . $line['line']; + } $out .= ']'; return $out; }