]> granicus.if.org Git - php/commitdiff
add local XMLRPC cache
authorChristian Dickmann <dickmann@php.net>
Sat, 6 Jul 2002 14:44:05 +0000 (14:44 +0000)
committerChristian Dickmann <dickmann@php.net>
Sat, 6 Jul 2002 14:44:05 +0000 (14:44 +0000)
pear/PEAR/Config.php
pear/PEAR/Remote.php

index 84a6f94400fb4c3cfe181c99a0b37cfac2f24a56..b039a0acd0ba4634d0cb400527b31f0beb06adeb 100644 (file)
@@ -19,6 +19,7 @@
 // $Id$
 
 require_once 'PEAR.php';
+require_once 'System.php';
 
 /**
  * Last created PEAR_Config instance.
@@ -49,6 +50,9 @@ define('PEAR_CONFIG_DEFAULT_DATADIR',
        PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'data');
 define('PEAR_CONFIG_DEFAULT_TESTDIR',
        PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'tests');
+
+define('PEAR_CONFIG_DEFAULT_CACHEDIR', (System::tmpdir()).'/pear/cache');
+
 if (@is_dir(PHP_SYSCONFDIR)) {
     define('PEAR_CONFIG_SYSCONFDIR', PHP_SYSCONFDIR);
 } else {
@@ -172,6 +176,13 @@ class PEAR_Config extends PEAR
             'prompt' => 'PEAR test directory',
             'group' => 'File Locations (Advanced)',
             ),
+        'cache_dir' => array(
+            'type' => 'directory',
+            'default' => PEAR_CONFIG_DEFAULT_CACHEDIR,
+            'doc' => 'directory which is used for XMLRPC cache',
+            'prompt' => 'PEAR Installer cache directory',
+            'group' => 'File Locations (Advanced)',
+            ),
         // Maintainers
         'username' => array(
             'type' => 'string',
@@ -215,6 +226,13 @@ class PEAR_Config extends PEAR
             'prompt' => 'Unix file mask',
             'group' => 'Advanced',
             ),
+        'cache_ttl' => array(
+            'type' => 'integer',
+            'default' => 0,
+            'doc' => 'amount of secs where the local cache is used and not updated',
+            'prompt' => 'Cache TimeToLive',
+            'group' => 'Advanced',
+            ),
 /*
         'testset1' => array(
             'type' => 'set',
index 4d892dd568bb6a94be0f9efd96d0a8cf3c6f11fc..ffc7af2fe449b78cd3fcb00558cb5687e52c89c8 100644 (file)
@@ -34,6 +34,7 @@ class PEAR_Remote extends PEAR
     // {{{ properties
 
     var $config = null;
+    var $cache  = null;
 
     // }}}
 
@@ -46,19 +47,63 @@ class PEAR_Remote extends PEAR
     }
 
     // }}}
-
+    
+    function getCache($args)
+    {
+        $id       = md5(serialize($args));
+        $cachedir = $this->config->get('cache_dir');
+        if (!file_exists($cachedir)) {
+            System::mkdir('-p '.$cachedir);
+        }
+        $filename = $cachedir.'/xmlrpc_cache_'.$id;
+        if (!file_exists($filename)) {
+            return null;
+        };
+        $result   = array(
+            'age'        => time() - filemtime($filename),
+            'lastChange' => filemtime($filename),
+            'content'    => unserialize(implode('', file($filename))),
+            );
+        return $result;
+    }
+    
+    function saveCache($args, $data)
+    {
+        $id       = md5(serialize($args));
+        $cachedir = $this->config->get('cache_dir');
+        if (!file_exists($cachedir)) {
+            System::mkdir('-p '.$cachedir);
+        }
+        $filename = $cachedir.'/xmlrpc_cache_'.$id;
+        
+        $fp = @fopen($filename, "w");
+        if ($fp !== null) {
+            fwrite($fp, serialize($data));
+            fclose($fp);
+        };
+    }
+    
     // {{{ call(method, [args...])
 
     function call($method)
     {
+        $_args = $args = func_get_args();
+        
+        $this->cache = $this->getCache($args);
+        $cachettl = $this->config->get('cache_ttl');
+        // If cache is newer than $cachettl seconds, we use the cache!
+        if ($this->cache !== null && $this->cache['age'] < $cachettl) {
+            return $this->cache['content'];
+        };
+        
         if (extension_loaded("xmlrpc")) {
-            $args = func_get_args();
-            return call_user_func_array(array(&$this, 'call_epi'), $args);
+            $result = call_user_func_array(array(&$this, 'call_epi'), $args);
+            $this->saveCache($_args, $result);
+            return $result;
         }
         if (!@include_once("XML/RPC.php")) {
             return $this->raiseError("For this remote PEAR operation you need to install the XML_RPC package");
         }
-        $args = func_get_args();
         array_shift($args);
         $server_host = $this->config->get('master_server');
         $username = $this->config->get('username');
@@ -66,7 +111,12 @@ class PEAR_Remote extends PEAR
         $eargs = array();
         foreach($args as $arg) $eargs[] = $this->_encode($arg);
         $f = new XML_RPC_Message($method, $eargs);
-        $c = new XML_RPC_Client('/xmlrpc.php', $server_host, 80);
+        if ($this->cache !== null) {
+            $maxAge = '?maxAge='.$this->cache['lastChange'];
+        } else {
+            $maxAge = '';
+        };
+        $c = new XML_RPC_Client('/xmlrpc.php'.$maxAge, $server_host, 80);
         if ($username && $password) {
             $c->setCredentials($username, $password);
         }
@@ -79,10 +129,15 @@ class PEAR_Remote extends PEAR
         }
         $v = $r->value();
         if ($e = $r->faultCode()) {
+            if ($e == $GLOBALS['XML_RPC_err']['http_error'] && strstr($r->faultString(), '304 Not Modified') !== false) {
+                return $this->cache['content'];
+            }
             return $this->raiseError($r->faultString(), $e);
         }
 
-        return XML_RPC_decode($v);
+        $result = XML_RPC_decode($v);
+        $this->saveCache($_args, $result);
+        return $result;
     }
 
     // }}}
@@ -139,22 +194,31 @@ class PEAR_Remote extends PEAR
             $tmp = base64_encode("$username:$password");
             $req_headers .= "Authorization: Basic $tmp\r\n";
         }
+        if ($this->cache !== null) {
+            $maxAge = '?maxAge='.$this->cache['lastChange'];
+        } else {
+            $maxAge = '';
+        };
+        
         if ($this->config->get('verbose') > 3) {
             print "XMLRPC REQUEST HEADERS:\n";
             var_dump($req_headers);
             print "XMLRPC REQUEST BODY:\n";
             var_dump($request);
         }
-        fwrite($fp, ("POST /xmlrpc.php HTTP/1.0\r\n$req_headers\r\n$request"));
+        
+        fwrite($fp, ("POST /xmlrpc.php$maxAge HTTP/1.0\r\n$req_headers\r\n$request"));
         $response = '';
         $line1 = fgets($fp, 2048);
         if (!preg_match('!^HTTP/[0-9\.]+ (\d+) (.*)!', $line1, $matches)) {
             return $this->raiseError("PEAR_Remote: invalid HTTP response from XML-RPC server");
         }
         switch ($matches[1]) {
-            case "200":
+            case "200": // OK
                 break;
-            case "401":
+            case "304": // Not Modified
+                return $this->cache['content'];
+            case "401": // Unauthorized
                 if ($username && $password) {
                     return $this->raiseError("PEAR_Remote: authorization failed", 401);
                 } else {