Swoole Coroutine Redis Client

Notice: ext-swoole is supported until v4.7.1, use ext-openswoole >= v4.7.1. Latest version: pecl install openswoole-4.8.1

Redis Coroutine Support

Since Swoole v4.3+ a new feature called hooks has been implemented, which allows Swoole to listen for internal PHP API calls, take control and execute your code in a non-blocking way, allowing us to use well known and tested libraries like phpredis or predis. The benefit of using hooks is it allows us to use existing PHP ecosystem tools and not force us to use any coroutine specific clients, instead Swoole aims to support the existing ecosystem.

Swoole hooks are not just for enabling coroutine support with Redis, there are many different hooks which enable traditional blocking code to be executed in a non-blocking manner.

You can use either phpredis or predis with Swoole\Runtime::enableCoroutine to enable the coroutine support for Redis. The runtime hook is what enables support and allows you to use existing PHP libraries. The actual individual hook that Redis clients require is the SWOOLE_HOOK_TCP, this is because both phpredis and predis are based on php_stream. Because php_stream is supported at low level it means phpredis or predis is 100% supported.

To make use of native Redis clients you can consider phpredis and predis.

Notice: If you are using the Swoole\Coroutine\Redis client API, this is now outdated and you should migrate over to using the new Coroutine Hook API for support with Redis

Example

<?php

// Enable the runtime hook for php_stream which supports Redis clients
Co::set(['hook_flags' => SWOOLE_HOOK_TCP]);

// Coroutine Context
Co\run(function()
{
    // Perform 100 operations concurrently...
    for($c = 100; $c--;)
    {
        // Coroutine 1
        go(function()
        {
            $redis = new Redis();
            $redis->connect('127.0.0.1', 6379);
            var_dump($redis->get('key'));
        });

        // Coroutine 2
        go(function()
        {
            $redis = new Redis();
            $redis->connect('127.0.0.1', 6379);

            $redis->lpush("redis-client-support", "phpredis");
            $redis->lpush("redis-client-support", "predis");

            $supportList = $redis->lrange("redis-client-support", 0, -1);
            var_dump($supportList);
        });
    }
});

The example above has created a coroutine context using Co\run but this does not need to be done if you are running a Swoole Server as it is done for you for each request.

Because Swoole Coroutine hooks are enabled the Redis method calls do not block the program, instead context switching being coroutines will happen, meaning no time is wasted when waiting for IO operations, this happens automatically for you, Swoole manages context switching, all you have to do is use Co\run to create a coroutine context and use go() to create coroutines.

Remember to set the runtime hook SWOOLE_HOOK_TCP at the start of your script or before any Redis operations for full code coverage.