Coroutine Channel

What is a channel?

Channels are one of the most important concepts in Swoole PHP and coroutines.

A channel is a non-blocking primitive for communication between two or more coroutines, you can use a channel to communicate between different coroutines and manage data between them.

Because coroutines have access to the same memory space, they can conflict with modifying memory which could be dependant by another coroutine as they are running within user space, on the same thread.

That is why we can solve memory access conflicts and race conditions with the help of channels. It is similar to chan in Golang.

You can think of a channel like a PHP array but has support for working within inside a coroutine and will not block as all operations are done within memory.

The short name \chan is the alias of Swoole\Coroutine\Channel.

You can also use WaitGroup or batch, Barrier to sync coroutines.

Methods

Channel Class Properties

  • Swoole\Coroutine\Channel->$capacity: The queue capacity of the channel, set within the constructor when creating a new channel. Needs to be more than or equal to 1.

  • Swoole\Coroutine\Channel->$errCode: Get the error code status of the channel.

Return Value Constant Description
0 SWOOLE_CHANNEL_OK Default success, everything is working correctly, no errors
-1 SWOOLE_CHANNEL_TIMEOUT Timeout when pop fails (timeout)
-2 SWOOLE_CHANNEL_CLOSED The channel is closed


Quick Start Example

Here we show an example of a channel with a capacity of 1, pushing to the channel and waiting for the second coroutine to remove (pop) the data from the channel.

<?php

$chan = new Swoole\Coroutine\Channel(1);

Co\run(function () use ($chan) {

    $cid = Swoole\Coroutine::getuid();
    $i = 0;

    while (1) {
        co::sleep(1.0);
        $chan->push(['rand' => rand(1000, 9999), 'index' => $i]);
        echo "[coroutine $cid] - $i\n";
        $i++;
    }

});

Co\run(function () use ($chan) {

    $cid = Swoole\Coroutine::getuid();

    while(1) {
        $data = $chan->pop();
        echo "[coroutine $cid]\n";
        var_dump($data);
    }

});

Below is an example which shows how a channel works in a simple manner, we create a channel and set the max capacity to 1, push the $data to the channel and then remove (pop) from the channel to receive the data we initially put in.

Just make sure to pass your channels to each coroutine that needs access to it.

<?php

Co\run(function() {

    $data = 'Hello World!';

    $chan = new chan(1);
    $chan->push($data);
    $pop = $chan->pop();

    var_dump($pop);

});