X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fseekat;a=blobdiff_plain;f=lib%2FAPI%2FCall%2FDeferred.php;h=304ec363bf1d7acdbf59ecf80b2e418c12b217a8;hp=a01891f56531f72f90501f85be235b115878845c;hb=d38b3ae03472ba2f9af5009778574b23472bb3f7;hpb=2451d97f1cb7b97e445b4dd839835b8673a4d0fc diff --git a/lib/API/Call/Deferred.php b/lib/API/Call/Deferred.php index a01891f..304ec36 100644 --- a/lib/API/Call/Deferred.php +++ b/lib/API/Call/Deferred.php @@ -2,16 +2,13 @@ namespace seekat\API\Call; -use Exception; use http\{ Client, Client\Request, Client\Response }; -use React\Promise\ExtendedPromiseInterface; +use Psr\Log\LoggerInterface; use seekat\API; -use SplObserver; -use SplSubject; -class Deferred extends \React\Promise\Deferred implements SplObserver +final class Deferred { /** * The response importer @@ -34,6 +31,11 @@ class Deferred extends \React\Promise\Deferred implements SplObserver */ private $cache; + /** + * @var LoggerInterface + */ + private $logger; + /** * The executed request * @@ -48,6 +50,26 @@ class Deferred extends \React\Promise\Deferred implements SplObserver */ private $response; + /** + * @var mixed + */ + private $promise; + + /** + * @var \Closure + */ + private $resolve; + + /** + * @var \Closure + */ + private $reject; + + /** + * @var \Closure + */ + private $update; + /** * Create a deferred promise for the response of $request * @@ -56,102 +78,74 @@ class Deferred extends \React\Promise\Deferred implements SplObserver * @param Cache\Service $cache */ function __construct(API $api, Request $request, Cache\Service $cache = null) { - parent::__construct(function ($resolve, $reject) { - return $this->cancel($resolve, $reject); - }); - $this->request = $request; $this->client = $api->getClient(); + $this->logger = $api->getLogger(); $this->result = new Result($api); $this->cache = new Cache($cache); + $future = $api->getFuture(); + $context = $future->createContext(function() { + if ($this->response) { + /* we did finish in the meantime */ + $this->complete(); + } else { + $this->client->dequeue($this->request); + ($this->reject)("Cancelled"); + } + }); + $this->promise = $future->getPromise($context); + $this->resolve = API\Future\resolver($future, $context); + $this->reject = API\Future\rejecter($future, $context); + } + + function __invoke() { if ($this->cache->load($this->request, $cached)) { - $api->getLogger()->info("deferred -> cached", [ - "method" => $request->getRequestMethod(), - "url" => $request->getRequestUrl(), + $this->logger->info("deferred -> cached", [ + "method" => $this->request->getRequestMethod(), + "url" => $this->request->getRequestUrl(), ]); $this->response = $cached; - $this->complete( - [$this, "resolve"], - [$this, "reject"] - ); + $this->complete(); } else { - $this->client->attach($this); $this->client->enqueue($this->request, function(Response $response) use($cached) { if ($response->getResponseCode() == 304) { $this->response = $cached; } else { $this->response = $response; } - $this->complete( - [$this, "resolve"], - [$this, "reject"] - ); + $this->complete(); return true; }); - $api->getLogger()->info("deferred -> enqueued", [ - "method" => $request->getRequestMethod(), - "url" => $request->getRequestUrl(), + $this->logger->info("deferred -> enqueued", [ + "method" => $this->request->getRequestMethod(), + "url" => $this->request->getRequestUrl(), ]); /* start off */ $this->client->once(); } - } - /** - * Progress observer - * - * Import the response's data on success and resolve the promise. - * - * @param SplSubject $client The observed HTTP client - * @param Request $request The request which generated the update - * @param object $progress The progress information - */ - function update(SplSubject $client, Request $request = null, $progress = null) { - if ($request !== $this->request) { - return; - } - - $this->notify((object) compact("client", "request", "progress")); + return $this->promise; } /** * Completion callback - * @param callable $resolve - * @param callable $reject */ - private function complete(callable $resolve, callable $reject) { - $this->client->detach($this); - + private function complete() { if ($this->response) { try { $api = ($this->result)($this->response); $this->cache->save($this->request, $this->response); - $resolve($api); - } catch (Exception $e) { - $reject($e); + ($this->resolve)($api); + } catch (\Throwable $e) { + ($this->reject)($e); } } else { - $reject($this->client->getTransferInfo($this->request)->error); + ($this->reject)($this->client->getTransferInfo($this->request)->error); } } - /** - * Cancellation callback - * @param callable $resolve - * @param callable $reject - */ - private function cancel(callable $resolve, callable $reject) { - /* did we finish in the meantime? */ - if ($this->response) { - $this->complete($resolve, $reject); - } else { - $this->client->detach($this); - $this->client->dequeue($this->request); - $reject("Cancelled"); - } - } }