From f5c854906850f37a5b9f4816fe2b28de14353859 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Tue, 30 Nov 2010 09:57:02 -0500 Subject: Squashed commit of the following: commit 39fdd181d95d2c39a3ea1ca330b10a99a92b961f Author: Evan Prodromou Date: Mon Nov 29 10:37:49 2010 -0500 use cache key prefix for router cache key commit 4cb9e56941922489b83d6425c059cf770991e68f Author: Evan Prodromou Date: Mon Nov 29 10:31:21 2010 -0500 use a unique hashkey based on the software version and loaded plugins commit 44458b48aef719543e11f83b41fded65cbcb8be9 Author: Evan Prodromou Date: Sat Nov 27 17:04:15 2010 -0500 cache the NUM object commit 809c188307a9b4ada15f3d7fa573a6034341efef Author: Evan Prodromou Date: Sat Nov 27 15:44:12 2010 -0500 accelerate routing by pivoting paths on actions --- lib/router.php | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 4 deletions(-) diff --git a/lib/router.php b/lib/router.php index 9aaac7dfe..3ea93b708 100644 --- a/lib/router.php +++ b/lib/router.php @@ -33,13 +33,15 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { require_once 'Net/URL/Mapper.php'; -class StatusNet_URL_Mapper extends Net_URL_Mapper { +class StatusNet_URL_Mapper extends Net_URL_Mapper +{ private static $_singleton = null; + private $_actionToPath = array(); private function __construct() { } - + public static function getInstance($id = '__default__') { if (empty(self::$_singleton)) { @@ -53,10 +55,47 @@ class StatusNet_URL_Mapper extends Net_URL_Mapper { $result = null; if (Event::handle('StartConnectPath', array(&$path, &$defaults, &$rules, &$result))) { $result = parent::connect($path, $defaults, $rules); + if (array_key_exists('action', $defaults)) { + $action = $defaults['action']; + } elseif (array_key_exists('action', $rules)) { + $action = $rules['action']; + } else { + $action = null; + } + $this->_mapAction($action, $result); Event::handle('EndConnectPath', array($path, $defaults, $rules, $result)); } return $result; } + + protected function _mapAction($action, $path) + { + if (!array_key_exists($action, $this->_actionToPath)) { + $this->_actionToPath[$action] = array(); + } + $this->_actionToPath[$action][] = $path; + return; + } + + public function generate($values = array(), $qstring = array(), $anchor = '') + { + if (!array_key_exists('action', $values)) { + return parent::generate($values, $qstring, $anchor); + } + + $action = $values['action']; + + if (!array_key_exists($action, $this->_actionToPath)) { + return parent::generate($values, $qstring, $anchor); + } + + $oldPaths = $this->paths; + $this->paths = $this->_actionToPath[$action]; + $result = parent::generate($values, $qstring, $anchor); + $this->paths = $oldPaths; + + return $result; + } } /** @@ -87,11 +126,48 @@ class Router function __construct() { - if (!$this->m) { - $this->m = $this->initialize(); + if (empty($this->m)) { + $k = self::cacheKey(); + $m = Cache::get($k); + if (!empty($m)) { + $this->m = $m; + } else { + $this->m = $this->initialize(); + Cache::set($k, $this->m); + } } } + /** + * Create a unique hashkey for the router. + * + * The router's url map can change based on the version of the software + * you're running and the plugins that are enabled. To avoid having bad routes + * get stuck in the cache, the key includes a list of plugins and the software + * version. + * + * There can still be problems with a) differences in versions of the plugins and + * b) people running code between official versions, but these tend to be more + * sophisticated users who can grok what's going on and clear their caches. + * + * @return string cache key string that should uniquely identify a router + */ + + static function cacheKey() + { + $plugins = StatusNet::getActivePlugins(); + $names = array(); + + foreach ($plugins as $plugin) { + $names[] = $plugin[0]; + } + + $names = array_unique($names); + asort($names); + + return Cache::key('router:'.STATUSNET_VERSION.':'.implode(',', $names)); + } + function initialize() { $m = StatusNet_URL_Mapper::getInstance(); -- cgit v1.2.3