github: fix notices
[pharext/pharext.org] / app / Github / API / Call.php
index f40e4866f6b837764b4b999798bca96453f13560..21fd45f016fb808802531baa5113baa37dc3ef40 100644 (file)
@@ -3,10 +3,14 @@
 namespace app\Github\API;
 
 use app\Github\API;
+use app\Github\Storage\Item;
+use http\Client\Response;
 use http\QueryString;
 use http\Url;
 use merry\Config;
 
+use React\Promise;
+
 abstract class Call
 {
        /**
@@ -35,9 +39,19 @@ abstract class Call
        protected $query;
        
        /**
-        * Queue this call to the API client
+        * @var \React\Promise\Deferred
+        */
+       protected $deferred;
+       
+       /**
+        * @return Request
+        */
+       abstract protected function request();
+       
+       /**
+        * @return array
         */
-       abstract function enqueue(callable $callback);
+       abstract protected function response(Response $response);
        
        /**
         * @param API $api
@@ -47,6 +61,7 @@ abstract class Call
                $this->api = $api;
                $this->config = $this->api->getConfig();
                $this->url = new Url($this->config->api->url, null, 0);
+               $this->deferred = new Promise\Deferred;
                
                if ($args) {
                        $this->args = $args;
@@ -56,18 +71,29 @@ 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();
-                       }
+       /**
+        * @return \React\Promise\Promise
+        */
+       function __invoke() {
+               if ($this->readFromCache($this->result)) {
+                       return new Promise\FulfilledPromise($this->result);
+               } else {
+                       $this->api->getClient()->enqueue(
+                               $this->request(),
+                               function($response) {
+                                       try {
+                                               $result = $this->response($response);
+                                               if (!($result instanceof Promise\PromiseInterface)) {
+                                                       $this->deferred->resolve($result);
+                                               }
+                                       } catch (\Exception $e) {
+                                               $this->deferred->reject($e);
+                                       }
+                                       return true;
+                               }
+                       );
+                       return $this->deferred->promise();
                }
-               
-               $this->enqueue($callback);
-               return $this->api->getClient();
        }
        
        /**
@@ -92,28 +118,64 @@ abstract class Call
        }
        
        function getCacheKey() {
-               return sprintf("github:%s:%s:%s", $this->api->getToken(), $this, 
-                       new QueryString($this->args));
+               $args = $this->args;
+               unset($args["fresh"]);
+               if (isset($args["page"]) && !strcmp($args["page"], "1")) {
+                       unset($args["page"]);
+               }
+               ksort($args);
+               return sprintf("%s:%s:%s", $this->api->getToken(), $this, 
+                       new QueryString($args));
        }
 
-       function readFromCache(&$cached = null, &$ttl = null) {
-               if (empty($this->args["fresh"]) && ($cache = $this->api->getCacheStorage())) {
-                       $key = $this->getCacheKey();
-                       return $cache->get($key, $cached, $ttl);
+       function readFromCache(array &$value = null) {
+               if (!empty($this->args["fresh"])) {
+                       return false;
+               }
+               if (!($cache = $this->api->getCacheStorage())) {
+                       return false;
+               }
+               if (!strlen($key = $this->getCacheKey())) {
+                       return false;
+               }
+               if (!$cache->get($key, $cached)) {
+                       if ($cached) {
+                               $this->api->getLogger()->debug(
+                                       sprintf("Cache-Stale: $this [TTL=%d]", $cached->getTTL()),
+                                       $this->args);
+                       } else {
+                               $this->api->getLogger()->debug("Cache-Miss: $this", $this->args);
+                       }
+                       return false;
                }
-               return false;
+               if (null !== $this->api->getMaxAge() && $cached->getAge() > $this->api->getMaxAge()) {
+                       $this->api->getLogger()->debug("Cache-Refresh: $this", $this->args);
+                       return false;
+               }
+               $this->api->getLogger()->debug("Cache-Hit: $this", $this->args);
+               $value = $cached->getValue();
+               return true;
        }
        
-       function saveToCache($fresh) {
+       function saveToCache(array $fresh) {
                if (($cache = $this->api->getCacheStorage())) {
                        if (isset($this->config->storage->cache->{$this}->ttl)) {
                                $ttl = $this->config->storage->cache->{$this}->ttl;
                        } else {
-                               $ttl = 0;
+                               $ttl = null;
                        }
                        
                        $key = $this->getCacheKey();
-                       $cache->set($key, $fresh, $ttl);
+                       $cache->set($key, new Item($fresh, $ttl));
+                       $this->api->getLogger()->debug("Cache-Push: $this", $this->args);
+               }
+       }
+       
+       function dropFromCache() {
+               if (($cache = $this->api->getCacheStorage())) {
+                       $key = $this->getCacheKey();
+                       $cache->del($key);
+                       $this->api->getLogger()->debug("Cache-Drop: $this", $this->args);
                }
        }
 }