Introduction
Swoole handle async task via a coroutine system.
Coroutines are piece of code that can be executed in parallel.
Our first async process
In that example, we will connect to yahoo and google to get html content synchronously :
#!/usr/bin/php
<?php
$start = microtime(true);
\Co\run(function() {
// Download yahoo
$client = new \Swoole\Coroutine\Http\Client('www.yahoo.fr', 80, true);
$client->get('/');
$yahooHtml = $client->getBody();
$client->close();
// Download google
$client = new \Swoole\Coroutine\Http\Client('www.google.fr', 80, true);
$client->get('/');
$yahooHtml = $client->getBody();
$client->close();
});
echo microtime(true);
This code is not async and google wait that yahoo is done. On my computer, I get a result in 1.1160490512848 seconds
Note that the \Co\run is the coroutine context, also named coroutine container.
Now, we wan't to parallelize the two requests. Just add "go" function to create coroutines :
#!/usr/bin/php
<?php
$start = microtime(true);
\Co\run(function () {
// Download yahoo in coroutine
\Co\go(function() {
$client = new \Swoole\Coroutine\Http\Client('www.yahoo.fr', 80, false);
$client->get('/');
$yahooHtml = $client->getBody();
$client->close();
});
// Download google in another coroutine
\Co\go(function() {
$client = new \Swoole\Coroutine\Http\Client('www.google.fr', 80, false);
$client->get('/');
$yahooHtml = $client->getBody();
$client->close();
});
});
echo microtime(true) - $start;
In couroutines, the jobs are done async, which mean that yahoo and google run at the same time. Then the result in my computer is now 0.61365509033203 seconds
Communication between coroutines
Now we want to communicate between coroutines. This is the role of channel :
$channel = new \Co\Channel();
We can push message :
$channel->push('hello');
And pull message :
$greeting = $channel->pop();
Put it together, notify user when download complete, got :
#!/usr/bin/php
<?php
\Co\run(function () {
// Create channel
$channel = new \Co\Channel();
// Async download yahoo
\Co\go(function() use($channel) {
$client = new \Swoole\Coroutine\Http\Client('www.yahoo.fr', 80, false);
$client->get('/');
$yahooHtml = $client->getBody();
$client->close();
$channel->push('yahoo done');
});
// Async download google
\Co\go(function() use($channel) {
$client = new \Swoole\Coroutine\Http\Client('www.google.fr', 80, false);
$client->get('/');
$yahooHtml = $client->getBody();
$client->close();
$channel->push('google done');
});
// Wait and notify user
\Co\go(function() use($channel) {
for ($i = 0; $i < 2; $i++) {
echo $channel->pop() . "\n";
}
});
});
Top comments (0)