OpenSwoole\Coroutine::select

Latest version: pecl install openswoole-22.1.2 | composer require openswoole/core:22.1.5

Declaration

<?php OpenSwoole\Coroutine::select(array $read = [], array $write = [], float $timeout = -1): mixed {}

Parameters

read

Wait for a list of channels until data is available to pop()

write

Wait for a list of channels until data is available to push()

timeout

Wait until a period of time, seconds

Return

Returns an array of the following:

Two arrays including the channels ready to read or write.

Description

Since Open Swoole v4.10.0

Waiting on multiple coroutine channels until at least one is closed, ready to read or write.

The basic $chan->push() and $chan->pop() are blocking. You can implement non-blocking channel operations with co::select, implement non-blocking sends, receives, and even non-blocking multi-way selects.

To eliminate long tail latency on high concurrent system, you can use coroutines and co::select to send multiple identical concurrent request and the fastest response win.

Example

<?php declare(strict_types = 1);
Co::set(['hook_flags' => OpenSwoole\Runtime::HOOK_ALL]);

function fetchUrl($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($ch);
    curl_close($ch);
    return $output;
}

co::run(function () {
    $chan1 = new chan(1);
    $chan2 = new chan(1);

    go(function() use ($chan1) {
        $content = fetchUrl('https://openswoole.com/');
        $chan1->push(['content' => $content, 'chan' => 'chan1']);
    });

    go(function() use ($chan2) {
        $content = fetchUrl('https://www.google.com/');
        $chan2->push(['content' => $content, 'chan' => 'chan2']);
    });

    $ret = co::select([$chan1, $chan2], [], 10);
    $content = array_values($ret['read'])[0]->pop();
    var_dump($content);
});
Last updated on September 17, 2022