summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvan Prodromou <evan@status.net>2010-11-30 09:57:02 -0500
committerEvan Prodromou <evan@status.net>2010-11-30 09:58:00 -0500
commitf5c854906850f37a5b9f4816fe2b28de14353859 (patch)
treea0aa9296c662c7146e472139dbae3d477841d612
parent806832e3392d6f2a824bc368dae4bc2831da39fa (diff)
Squashed commit of the following:
commit 39fdd181d95d2c39a3ea1ca330b10a99a92b961f Author: Evan Prodromou <evan@status.net> Date: Mon Nov 29 10:37:49 2010 -0500 use cache key prefix for router cache key commit 4cb9e56941922489b83d6425c059cf770991e68f Author: Evan Prodromou <evan@status.net> 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 <evan@status.net> Date: Sat Nov 27 17:04:15 2010 -0500 cache the NUM object commit 809c188307a9b4ada15f3d7fa573a6034341efef Author: Evan Prodromou <evan@status.net> Date: Sat Nov 27 15:44:12 2010 -0500 accelerate routing by pivoting paths on actions
-rw-r--r--lib/router.php84
1 files 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();