DEV Community

sebk69
sebk69

Posted on • Edited on

2

Let's demystify swoole : coroutines

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);
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

We can push message :

$channel->push('hello');
Enter fullscreen mode Exit fullscreen mode

And pull message :

$greeting = $channel->pop();
Enter fullscreen mode Exit fullscreen mode

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";
        }
    });
});
Enter fullscreen mode Exit fullscreen mode

Other posts on swoole

Sentry blog image

How I fixed 20 seconds of lag for every user in just 20 minutes.

Our AI agent was running 10-20 seconds slower than it should, impacting both our own developers and our early adopters. See how I used Sentry Profiling to fix it in record time.

Read more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Dive into an ocean of knowledge with this thought-provoking post, revered deeply within the supportive DEV Community. Developers of all levels are welcome to join and enhance our collective intelligence.

Saying a simple "thank you" can brighten someone's day. Share your gratitude in the comments below!

On DEV, sharing ideas eases our path and fortifies our community connections. Found this helpful? Sending a quick thanks to the author can be profoundly valued.

Okay