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
{
/**
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
$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;
}
}
- 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 {
+ $this->deferred->resolve($this->response($response));
+ } catch (\Exception $e) {
+ $this->deferred->reject($e);
+ }
+ return true;
+ }
+ );
+ return $this->deferred->promise();
}
-
- $this->enqueue($callback);
- return $this->api->getClient();
}
/**
}
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)) {
+ return false;
}
- return false;
+ if (null !== $this->api->getMaxAge() && $cached->getAge() > $this->api->getMaxAge()) {
+ 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));
+ }
+ }
+
+ function dropFromCache() {
+ if (($cache = $this->api->getCacheStorage())) {
+ $key = $this->getCacheKey();
+ $cache->del($key);
}
}
}