Skip to content

Commit 8eb3bf6

Browse files
authored
Merge pull request #4 from clue-labs/blocking
Documentation and example for blocking integration
2 parents d5c0384 + ea48088 commit 8eb3bf6

File tree

2 files changed

+122
-0
lines changed

2 files changed

+122
-0
lines changed

README.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ much any API that already uses Promises.
3838
* [Promises](#promises)
3939
* [Cancellation](#cancellation)
4040
* [Timeout](#timeout)
41+
* [Blocking](#blocking)
4142
* [Install](#install)
4243
* [Tests](#tests)
4344
* [License](#license)
@@ -197,6 +198,9 @@ promise which will start the actual operation once another operation is
197198
completed. This means that this is handled entirely transparently and you do not
198199
need to worry about this concurrency limit yourself.
199200

201+
If this looks strange to you, you can also use the more traditional
202+
[blocking API](#blocking).
203+
200204
#### Cancellation
201205

202206
The returned Promise is implemented in such a way that it can be cancelled
@@ -254,6 +258,75 @@ $promise = Timer\timeout($q($url), 2.0, $loop);
254258
Please refer to [react/promise-timer](https://github.com/reactphp/promise-timer)
255259
for more details.
256260

261+
#### Blocking
262+
263+
As stated above, this library provides you a powerful, async API by default.
264+
If, however, you want to integrate this into your traditional, blocking
265+
environment, you may want to look into also using
266+
[clue/block-react](https://github.com/clue/php-block-react).
267+
268+
The resulting blocking code that awaits a number of concurrent HTTP requests
269+
could look something like this:
270+
271+
```php
272+
use Clue\React\Block;
273+
274+
$loop = React\EventLoop\Factory::create();
275+
$browser = new Clue\React\Buzz\Browser($loop);
276+
277+
$q = new Queue(10, null, function ($url) use ($browser) {
278+
return $browser->get($url);
279+
});
280+
281+
$promises = array(
282+
$q('http://example.com/'),
283+
$q('http://www.example.org/'),
284+
$q('http://example.net/'),
285+
);
286+
287+
try {
288+
$responses = Block\awaitAll($promises, $loop);
289+
// responses successfully received
290+
} catch (Exception $e) {
291+
// an error occured while performing the requests
292+
}
293+
```
294+
295+
Similarly, you can also wrap this in a function to provide a simple API and hide
296+
all the async details from the outside:
297+
298+
```php
299+
/**
300+
* Concurrently downloads all the given URIs
301+
*
302+
* @param string[] $uris list of URIs to download
303+
* @return ResponseInterface[] map with a response object for each URI
304+
* @throws Exception if any of the URIs can not be downloaded
305+
*/
306+
function download(array $uris)
307+
{
308+
$loop = React\EventLoop\Factory::create();
309+
$browser = new Clue\React\Buzz\Browser($loop);
310+
311+
$q = new Queue(10, null, function ($uri) use ($browser) {
312+
return $browser->get($uri);
313+
});
314+
315+
$promises = array();
316+
foreach ($uris as $uri) {
317+
$promises[$uri] = $q($uri);
318+
}
319+
320+
return Clue\React\Block\awaitAll($promises, $loop);
321+
}
322+
```
323+
324+
Please refer to [clue/block-react](https://github.com/clue/php-block-react#readme)
325+
for more details.
326+
327+
> Keep in mind that returning an array of response messages means that the whole
328+
response body has to be kept in memory.
329+
257330
## Install
258331

259332
The recommended way to install this library is [through Composer](https://getcomposer.org).

examples/11-http-blocking.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
use Clue\React\Block;
4+
use Clue\React\Buzz\Browser;
5+
use Clue\React\Mq\Queue;
6+
use Psr\Http\Message\ResponseInterface;
7+
use React\EventLoop\Factory;
8+
9+
require __DIR__ . '/../vendor/autoload.php';
10+
11+
// list of all URLs you want to download
12+
// this list may potentially contain hundreds or thousands of entries
13+
$urls = array(
14+
'http://www.github.com/',
15+
'http://www.yahoo.com/',
16+
'http://www.bing.com/',
17+
'http://www.bing.com/invalid',
18+
'http://www.google.com/',
19+
);
20+
21+
function download(array $urls)
22+
{
23+
$loop = Factory::create();
24+
$browser = new Browser($loop);
25+
26+
$queue = new Queue(3, null, function ($url) use ($browser) {
27+
return $browser->get($url);
28+
});
29+
30+
$promises = array();
31+
foreach ($urls as $url) {
32+
$promises[$url] = $queue($url)->then(
33+
function (ResponseInterface $response) use ($url) {
34+
return $response->getBody();
35+
},
36+
function (Exception $e) use ($url) {
37+
return null;
38+
}
39+
);
40+
}
41+
42+
return Block\awaitAll($promises, $loop);
43+
}
44+
45+
$responses = download($urls);
46+
47+
foreach ($responses as $url => $response) {
48+
echo $url . ' is ' . strlen($response) . ' bytes' . PHP_EOL;
49+
}

0 commit comments

Comments
 (0)