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() : Promise { if ($this->cache->load($this->request, $cached)) { $this->logger->info("deferred -> cached", [ "method" => $this->request->getRequestMethod(), "url" => $this->request->getRequestUrl(), ]); $this->response = $cached; $this->complete(); } else { $this->client->enqueue($this->request, function(Response $response) use($cached) { if ($response->getResponseCode() == 304) { $this->response = $cached; } else { $this->response = $response; } $this->complete(); return true; }); $this->logger->info("deferred -> enqueued", [ "method" => $this->request->getRequestMethod(), "url" => $this->request->getRequestUrl(), ]); /* start off */ $this->client->once(); } return $this->promise; } /** * Completion callback */ private function complete() { if ($this->response) { try { $api = ($this->result)($this->response); $this->cache->save($this->request, $this->response); ($this->resolve)($api); } catch (\Throwable $e) { ($this->reject)($e); } } else { ($this->reject)($this->client->getTransferInfo($this->request)->error); } } }