add redis cache storage
authorMichael Wallner <mike@php.net>
Mon, 11 May 2015 15:35:46 +0000 (17:35 +0200)
committerMichael Wallner <mike@php.net>
Mon, 11 May 2015 15:35:46 +0000 (17:35 +0200)
app/Github/API/Call.php
app/Github/Storage/Redis.php [new file with mode: 0644]
app/bootstrap/github.php

index ea9b59a70c461e7d0837e6e650c0eaf8c408e573..8b09d27f451b40a935ce97780659b0cbd3acd596 100644 (file)
@@ -57,16 +57,13 @@ abstract class Call
        }
        
        function __invoke(callable $callback) {
-               if (empty($this->args["fresh"]) && ($cache = $this->api->getCacheStorage())) {
-                       $key = $this->getCacheKey();
-                       
-                       if ($cache->get($key, $cached)) {
-                               call_user_func_array($callback, $cached);
-                               return $this->api->getClient();
-                       }
+               if ($this->readFromCache($cached)) {
+                       header("X-Cache-Hit: $this", false);
+                       call_user_func_array($callback, $cached);
+               } else {
+                       header("X-Cache-Miss: $this", false);
+                       $this->enqueue($callback);
                }
-               
-               $this->enqueue($callback);
                return $this;
        }
        
@@ -119,7 +116,7 @@ abstract class Call
                        if (isset($this->config->storage->cache->{$this}->ttl)) {
                                $ttl = $this->config->storage->cache->{$this}->ttl;
                        } else {
-                               $ttl = 0;
+                               $ttl = null;
                        }
                        
                        $key = $this->getCacheKey();
diff --git a/app/Github/Storage/Redis.php b/app/Github/Storage/Redis.php
new file mode 100644 (file)
index 0000000..5833a5b
--- /dev/null
@@ -0,0 +1,85 @@
+<?php
+
+namespace app\Github\Storage;
+
+use app\Github\Storage;
+
+class Redis implements Storage
+{
+       private $rd;
+       private $ns;
+
+       function __construct($ns = "github", \Redis $rd = null) {
+               $this->ns = $ns;
+               if (!$rd) {
+                       $rd = new \Redis();
+                       $rd->open("localhost");
+                       $rd->setOption(\Redis::OPT_SERIALIZER, \Redis::SERIALIZER_PHP);
+               }
+               $this->rd = $rd;
+       }
+
+       private function key($key) {
+               return sprintf("%s:%s", $this->ns, $key);
+       }
+
+       function get($key, &$val = null, &$ltl = null, $update = false) {
+               if (!$item = $this->rd->get($this->key($key))) {
+                       header("Cache-Item: ".serialize($item), false);
+                       return false;
+               }
+
+               $val = $item->value;
+               $ttl = $item->ttl;
+               $set = $item->time;
+
+               if (!isset($ttl)) {
+                       return true;
+               }
+               $now = time();
+               $ltl = $ttl - ($now - $set);
+               header("X-Cache-Times: ltl=$ltl,now=$now,set=$set,ttl=$ttl", false);
+               if ($ltl >= 0) {
+                       if ($update) {
+                               $item->time = time();
+                               $this->rd->setex($this->key($key), $ttl + 60*60*24, $item);
+                       }
+                       return true;
+               }
+               return false;
+       }
+
+       function set($key, $val, $ttl = null) {
+               $item = new Redis\Item([
+                       "value" => $val,
+                       "ttl" => $ttl,
+                       "time" => isset($ttl) ? time() : null
+               ]);
+               if (isset($ttl)) {
+                       $this->rd->set($this->key($key), $item);
+               } else {
+                       $this->rd->setex($this->key($key), $ttl + 60*60*24, $item);
+               }
+               return $this;
+       }
+
+       function del($key) {
+               $this->rd->delete($this->key($key));
+       }
+}
+
+namespace app\Github\Storage\Redis;
+
+class Item
+{
+       public $value;
+       public $time;
+       public $ttl;
+
+       function __construct(array $data) {
+               foreach ($data as $key => $val) {
+                       $this->$key = $val;
+               }
+       }
+}
+
index 04396fb6cfaf30a1b849439c269150e68a5099ee..0ec014e09c00d7c0aac54c26e19da76d82ae6bd2 100644 (file)
@@ -17,9 +17,10 @@ $injector->share(Github\API::class)
                                0);
                }
                return new Github\API(
-                       $config->github
-                  ,new Github\Storage\Session("gh-tokens")
+                        $config->github
+                       ,new Github\Storage\Session("gh-tokens")
                   #,new Github\Storage\Memcache("gh-cache")
+                       ,new Github\Storage\Redis("gh-cache")
           );
        });