Skip to content
This repository was archived by the owner on Jan 6, 2024. It is now read-only.

Commit 27e36f9

Browse files
committed
Add async capability
1 parent c887235 commit 27e36f9

File tree

3 files changed

+134
-3
lines changed

3 files changed

+134
-3
lines changed

composer.json

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,23 @@
1616
],
1717
"require": {
1818
"php": ">=5.5.0",
19-
"php-http/httplug": "dev-master",
19+
"php-http/httplug": "dev-feature/async as 1.0.1",
2020
"guzzlehttp/guzzle": "^6.0"
2121
},
2222
"require-dev": {
2323
"ext-curl": "*",
24-
"php-http/adapter-integration-tests": "^0.2@dev"
24+
"php-http/adapter-integration-tests": "dev-feature/async-test"
2525
},
26+
"repositories": [
27+
{
28+
"type": "vcs",
29+
"url": "https://github.com/joelwurtz/httplug"
30+
},
31+
{
32+
"type": "vcs",
33+
"url": "https://github.com/joelwurtz/adapter-integration-tests"
34+
}
35+
],
2636
"provide": {
2737
"php-http/client-implementation": "1.0"
2838
},

src/Guzzle6HttpAdapter.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@
1818
use Http\Client\Exception\NetworkException;
1919
use Http\Client\Exception\RequestException;
2020
use Http\Client\Exception\TransferException;
21+
use Http\Client\HttpAsyncClient;
2122
use Http\Client\HttpClient;
2223
use Psr\Http\Message\RequestInterface;
2324

2425
/**
2526
* @author David de Boer <[email protected]>
2627
*/
27-
class Guzzle6HttpAdapter implements HttpClient
28+
class Guzzle6HttpAdapter implements HttpClient, HttpAsyncClient
2829
{
2930
/**
3031
* @var ClientInterface
@@ -53,6 +54,14 @@ public function sendRequest(RequestInterface $request)
5354
}
5455
}
5556

57+
/**
58+
* {@inheritdoc}
59+
*/
60+
public function sendAsyncRequest(RequestInterface $request)
61+
{
62+
return new Guzzle6Promise($this->client->sendAsync($request));
63+
}
64+
5665
/**
5766
* Converts a Guzzle exception into an Httplug exception.
5867
*

src/Guzzle6Promise.php

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?php
2+
3+
namespace Http\Adapter;
4+
5+
use GuzzleHttp\Exception\RequestException;
6+
use GuzzleHttp\Promise\PromiseInterface;
7+
use Http\Client\Exception;
8+
use Http\Client\Promise;
9+
use Psr\Http\Message\ResponseInterface;
10+
11+
class Guzzle6Promise implements Promise
12+
{
13+
/**
14+
* @var \GuzzleHttp\Promise\PromiseInterface
15+
*/
16+
private $promise;
17+
18+
/**
19+
* @var string State of the promise
20+
*/
21+
private $state;
22+
23+
/**
24+
* @var ResponseInterface
25+
*/
26+
private $response;
27+
28+
/**
29+
* @var Exception
30+
*/
31+
private $error;
32+
33+
public function __construct(PromiseInterface $promise)
34+
{
35+
$this->promise = $promise;
36+
$this->state = self::PENDING;
37+
}
38+
39+
/**
40+
* {@inheritdoc}
41+
*/
42+
public function then(callable $onFulfilled = null, callable $onRejected = null)
43+
{
44+
$onFulfilledInternal = function ($response) use($onFulfilled) {
45+
$this->response = $response;
46+
$this->state = self::FULFILLED;
47+
48+
return $onFulfilled($this->response);
49+
};
50+
51+
$onRejectedInternal = function ($reason) use($onRejected) {
52+
if (!($reason instanceof RequestException)) {
53+
throw new \RuntimeException("Invalid reason");
54+
}
55+
56+
$this->state = self::REJECTED;
57+
$this->error = new Exception\NetworkException($reason->getMessage(), $reason->getRequest(), $reason);
58+
59+
if ($reason->hasResponse()) {
60+
$this->error = new Exception\HttpException($reason->getMessage(), $reason->getRequest(), $reason->getResponse(), $reason);
61+
}
62+
63+
return $onRejected($this->error);
64+
};
65+
66+
$this->promise = $this->promise->then($onFulfilledInternal, $onRejectedInternal);
67+
68+
return new static($this->promise);
69+
}
70+
71+
/**
72+
* {@inheritdoc}
73+
*/
74+
public function getState()
75+
{
76+
return $this->state;
77+
}
78+
79+
80+
/**
81+
* {@inheritdoc}
82+
*/
83+
public function getResponse()
84+
{
85+
if (self::FULFILLED !== $this->state) {
86+
throw new \LogicException("Response not available for the current state");
87+
}
88+
89+
return $this->response;
90+
}
91+
92+
/**
93+
* {@inheritdoc}
94+
*/
95+
public function getError()
96+
{
97+
if (self::REJECTED !== $this->state) {
98+
throw new \LogicException("Error not available for the current state");
99+
}
100+
101+
return $this->error;
102+
}
103+
104+
/**
105+
* {@inheritdoc}
106+
*/
107+
public function wait()
108+
{
109+
$this->promise->wait(false);
110+
}
111+
}
112+

0 commit comments

Comments
 (0)