Skip to content

Commit d9f22d0

Browse files
committed
Merge branch 'improved-async'
2 parents ed7716d + 16b51ce commit d9f22d0

File tree

4 files changed

+126
-140
lines changed

4 files changed

+126
-140
lines changed

README.md

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -87,19 +87,15 @@ $satoshi = \Denpa\Bitcoin\to_satoshi($bitcoin);
8787
```
8888
To send asynchronous request, add Async to method name:
8989
```php
90-
use Denpa\Bitcoin\BitcoindResponse;
91-
92-
$promise = $bitcoind->getBlockAsync(
90+
$bitcoind->getBlockAsync(
9391
'000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f',
94-
function (BitcoindResponse $success) {
95-
//
92+
function ($response) {
93+
// success
9694
},
97-
function (\Exception $exception) {
98-
//
95+
function ($exception) {
96+
// error
9997
}
10098
);
101-
102-
$promise->wait();
10399
```
104100

105101
You can also send requests using request method:
@@ -131,20 +127,16 @@ $txid = $result->get();
131127
```
132128
or requestAsync method for asynchronous calls:
133129
```php
134-
use Denpa\Bitcoin\BitcoindResponse;
135-
136-
$promise = $bitcoind->requestAsync(
130+
$bitcoind->requestAsync(
137131
'getBlock',
138132
'000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f',
139-
function (BitcoindResponse $success) {
140-
//
133+
function ($response) {
134+
// success
141135
},
142-
function (\Exception $exception) {
143-
//
136+
function ($exception) {
137+
// error
144138
}
145139
);
146-
147-
$promise->wait();
148140
```
149141

150142
## Multi-Wallet RPC

src/Client.php

Lines changed: 74 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use GuzzleHttp\Exception\RequestException;
88
use GuzzleHttp\HandlerStack;
99
use GuzzleHttp\Middleware;
10+
use GuzzleHttp\Promise;
1011
use Psr\Http\Message\ResponseInterface;
1112

1213
class Client
@@ -25,6 +26,13 @@ class Client
2526
*/
2627
protected $config;
2728

29+
/**
30+
* Array of GuzzleHttp promises.
31+
*
32+
* @var array
33+
*/
34+
protected $promises = [];
35+
2836
/**
2937
* URL path.
3038
*
@@ -60,6 +68,18 @@ public function __construct($config = [])
6068
]);
6169
}
6270

71+
/**
72+
* Wait for all promises on object destruction.
73+
*
74+
* @return void
75+
*/
76+
public function __destruct()
77+
{
78+
if (!empty($this->promises)) {
79+
Promise\settle($this->promises)->wait();
80+
}
81+
}
82+
6383
/**
6484
* Gets http client config.
6585
*
@@ -124,10 +144,8 @@ public function wallet($name)
124144
public function request($method, ...$params)
125145
{
126146
try {
127-
$response = $this->client->request(
128-
'POST',
129-
$this->path,
130-
['json' => $this->makeJson($method, $params)]);
147+
$response = $this->client
148+
->post($this->path, $this->makeJson($method, $params));
131149

132150
if ($response->hasError()) {
133151
// throw exception on error
@@ -136,17 +154,7 @@ public function request($method, ...$params)
136154

137155
return $response;
138156
} catch (RequestException $exception) {
139-
if (
140-
$exception->hasResponse() &&
141-
$exception->getResponse()->hasError()
142-
) {
143-
throw new Exceptions\BitcoindException($exception->getResponse()->error());
144-
}
145-
146-
throw new Exceptions\ClientException(
147-
$exception->getMessage(),
148-
$exception->getCode()
149-
);
157+
throw $this->handleException($exception);
150158
}
151159
}
152160

@@ -155,31 +163,29 @@ public function request($method, ...$params)
155163
*
156164
* @param string $method
157165
* @param mixed $params
158-
* @param callable|null $onFullfiled
159-
* @param callable|null $onRejected
166+
* @param callable|null $fulfilled
167+
* @param callable|null $rejected
160168
*
161169
* @return \GuzzleHttp\Promise\Promise
162170
*/
163171
public function requestAsync(
164172
$method,
165173
$params = [],
166-
callable $onFullfiled = null,
167-
callable $onRejected = null)
174+
callable $fulfilled = null,
175+
callable $rejected = null)
168176
{
169-
$promise = $this->client->requestAsync(
170-
'POST',
171-
$this->path,
172-
['json' => $this->makeJson($method, $params)]
173-
);
177+
$promise = $this->client
178+
->postAsync($this->path, $this->makeJson($method, $params));
174179

175-
$promise->then(
176-
function (ResponseInterface $response) use ($onFullfiled) {
177-
$this->asyncFulfilled($response, $onFullfiled);
178-
},
179-
function (RequestException $exception) use ($onRejected) {
180-
$this->asyncRejected($exception, $onRejected);
181-
}
182-
);
180+
$promise->then(function ($response) use ($fulfilled) {
181+
$this->onSuccess($response, $fulfilled);
182+
});
183+
184+
$promise->otherwise(function ($exception) use ($rejected) {
185+
$this->onError($exception, $rejected);
186+
});
187+
188+
$this->promises[] = $promise;
183189

184190
return $promise;
185191
}
@@ -194,9 +200,8 @@ function (RequestException $exception) use ($onRejected) {
194200
*/
195201
public function __call($method, array $params = [])
196202
{
197-
$method = str_ireplace('async', '', $method, $count);
198-
if ($count > 0) {
199-
return $this->requestAsync($method, ...$params);
203+
if (strtolower(substr($method, -5)) == 'async') {
204+
return $this->requestAsync(substr($method, 0, -5), ...$params);
200205
}
201206

202207
return $this->request($method, ...$params);
@@ -326,9 +331,11 @@ protected function parseUrl($config)
326331
protected function makeJson($method, $params = [])
327332
{
328333
return [
329-
'method' => strtolower($method),
330-
'params' => (array) $params,
331-
'id' => $this->rpcId++,
334+
'json' => [
335+
'method' => strtolower($method),
336+
'params' => (array) $params,
337+
'id' => $this->rpcId++,
338+
],
332339
];
333340
}
334341

@@ -340,15 +347,14 @@ protected function makeJson($method, $params = [])
340347
*
341348
* @return void
342349
*/
343-
protected function asyncFulfilled(ResponseInterface $response, callable $callback = null)
350+
protected function onSuccess(ResponseInterface $response, callable $callback = null)
344351
{
345-
$error = null;
346-
if ($response->hasError()) {
347-
$error = new Exceptions\BitcoindException($response->error());
348-
}
352+
if (!is_null($callback)) {
353+
if ($response->hasError()) {
354+
$response = new Exceptions\BitcoindException($response->error());
355+
}
349356

350-
if (is_callable($callback)) {
351-
$callback($error ?: $response);
357+
$callback($response);
352358
}
353359
}
354360

@@ -360,26 +366,33 @@ protected function asyncFulfilled(ResponseInterface $response, callable $callbac
360366
*
361367
* @return void
362368
*/
363-
protected function asyncRejected(RequestException $exception, callable $callback = null)
369+
protected function onError(RequestException $exception, callable $callback = null)
364370
{
365-
if (
366-
$exception->hasResponse() &&
367-
$exception->getResponse()->hasError()
368-
) {
369-
$exception = new Exceptions\BitcoindException(
370-
$exception->getResponse()->error()
371-
);
371+
if (!is_null($callback)) {
372+
$callback($this->handleException($exception));
372373
}
374+
}
373375

374-
if ($exception instanceof RequestException) {
375-
$exception = new Exceptions\ClientException(
376-
$exception->getMessage(),
377-
$exception->getCode()
378-
);
379-
}
376+
/**
377+
* Handles exceptions.
378+
*
379+
* @param \Exception $exception
380+
*
381+
* @return \Exception
382+
*/
383+
protected function handleException($exception)
384+
{
385+
if ($exception->hasResponse()) {
386+
$response = $exception->getResponse();
380387

381-
if (is_callable($callback)) {
382-
$callback($exception);
388+
if ($response->hasError()) {
389+
return new Exceptions\BitcoindException($response->error());
390+
}
383391
}
392+
393+
return new Exceptions\ClientException(
394+
$exception->getMessage(),
395+
$exception->getCode()
396+
);
384397
}
385398
}

0 commit comments

Comments
 (0)