Skip to content

Commit a445cdb

Browse files
committed
Provide POC cross-compatibility between new and old plugins
The deprecated PluginClient now wraps the new one internally and dispatches the requests to it. Full BC should be preserved, relevant exceptions caught and rethrown with the appropriate wrapping.
1 parent 81264f2 commit a445cdb

File tree

1 file changed

+11
-103
lines changed

1 file changed

+11
-103
lines changed

src/PluginClient.php

Lines changed: 11 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,10 @@
22

33
namespace Http\Client\Plugin;
44

5-
use Http\Client\Common\EmulatedHttpAsyncClient;
6-
use Http\Client\Exception;
75
use Http\Client\HttpAsyncClient;
86
use Http\Client\HttpClient;
97
use Http\Client\Plugin\Exception\LoopException;
10-
use Http\Promise\FulfilledPromise;
11-
use Http\Promise\RejectedPromise;
128
use Psr\Http\Message\RequestInterface;
13-
use Symfony\Component\OptionsResolver\OptionsResolver;
149

1510
/**
1611
* The client managing plugins and providing a decorator around HTTP Clients.
@@ -22,25 +17,9 @@
2217
final class PluginClient implements HttpClient, HttpAsyncClient
2318
{
2419
/**
25-
* An HTTP async client.
26-
*
27-
* @var HttpAsyncClient
28-
*/
29-
private $client;
30-
31-
/**
32-
* The plugin chain.
33-
*
34-
* @var Plugin[]
35-
*/
36-
private $plugins;
37-
38-
/**
39-
* A list of options.
40-
*
41-
* @var array
20+
* @var \Http\Client\Common\PluginClient
4221
*/
43-
private $options;
22+
private $pluginClient;
4423

4524
/**
4625
* @param HttpClient|HttpAsyncClient $client
@@ -54,101 +33,30 @@ final class PluginClient implements HttpClient, HttpAsyncClient
5433
*/
5534
public function __construct($client, array $plugins = [], array $options = [])
5635
{
57-
if ($client instanceof HttpAsyncClient) {
58-
$this->client = $client;
59-
} elseif ($client instanceof HttpClient) {
60-
$this->client = new EmulatedHttpAsyncClient($client);
61-
} else {
62-
throw new \RuntimeException('Client must be an instance of Http\\Client\\HttpClient or Http\\Client\\HttpAsyncClient');
63-
}
64-
65-
$this->plugins = $plugins;
66-
$this->options = $this->configure($options);
36+
$this->pluginClient = new \Http\Client\Common\PluginClient($client, $plugins, $options);
6737
}
6838

6939
/**
7040
* {@inheritdoc}
7141
*/
7242
public function sendRequest(RequestInterface $request)
7343
{
74-
// If we don't have an http client, use the async call
75-
if (!($this->client instanceof HttpClient)) {
76-
return $this->sendAsyncRequest($request)->wait();
44+
try {
45+
return $this->pluginClient->sendRequest($request);
46+
} catch (\Http\Client\Common\Exception\LoopException $e) {
47+
throw new LoopException($e->getMessage(), $e->getRequest(), $e);
7748
}
78-
79-
// Else we want to use the synchronous call of the underlying client, and not the async one in the case
80-
// we have both an async and sync call
81-
$pluginChain = $this->createPluginChain($this->plugins, function (RequestInterface $request) {
82-
try {
83-
return new FulfilledPromise($this->client->sendRequest($request));
84-
} catch (Exception $exception) {
85-
return new RejectedPromise($exception);
86-
}
87-
});
88-
89-
return $pluginChain($request)->wait();
9049
}
9150

9251
/**
9352
* {@inheritdoc}
9453
*/
9554
public function sendAsyncRequest(RequestInterface $request)
9655
{
97-
$pluginChain = $this->createPluginChain($this->plugins, function (RequestInterface $request) {
98-
return $this->client->sendAsyncRequest($request);
99-
});
100-
101-
return $pluginChain($request);
102-
}
103-
104-
/**
105-
* Configure the plugin client.
106-
*
107-
* @param array $options
108-
*
109-
* @return array
110-
*/
111-
private function configure(array $options = [])
112-
{
113-
$resolver = new OptionsResolver();
114-
$resolver->setDefaults([
115-
'max_restarts' => 10,
116-
]);
117-
118-
return $resolver->resolve($options);
119-
}
120-
121-
/**
122-
* Create the plugin chain.
123-
*
124-
* @param Plugin[] $pluginList A list of plugins
125-
* @param callable $clientCallable Callable making the HTTP call
126-
*
127-
* @return callable
128-
*/
129-
private function createPluginChain($pluginList, callable $clientCallable)
130-
{
131-
$firstCallable = $lastCallable = $clientCallable;
132-
133-
while ($plugin = array_pop($pluginList)) {
134-
$lastCallable = function (RequestInterface $request) use ($plugin, $lastCallable, &$firstCallable) {
135-
return $plugin->handleRequest($request, $lastCallable, $firstCallable);
136-
};
137-
138-
$firstCallable = $lastCallable;
56+
try {
57+
return $this->pluginClient->sendAsyncRequest($request);
58+
} catch (\Http\Client\Common\Exception\LoopException $e) {
59+
throw new LoopException($e->getMessage(), $e->getRequest(), $e);
13960
}
140-
141-
$firstCalls = 0;
142-
$firstCallable = function (RequestInterface $request) use ($lastCallable, &$firstCalls) {
143-
if ($firstCalls > $this->options['max_restarts']) {
144-
throw new LoopException('Too many restarts in plugin client', $request);
145-
}
146-
147-
++$firstCalls;
148-
149-
return $lastCallable($request);
150-
};
151-
152-
return $firstCallable;
15361
}
15462
}

0 commit comments

Comments
 (0)