Open source PHP extension for Async IO, Coroutines and Fibers

Overview

Swoole Logo

lib-openswoole ext-openswoole test-linux Coverity Scan Build Status codecov

Swoole is an event-driven asynchronous & coroutine-based concurrency networking communication engine with high performance written in C++ for PHP.

Open Swoole since release version v4.7.1.

Event-based

The network layer in Swoole is event-based and takes full advantage of the underlying epoll/kqueue implementation, making it really easy to serve millions of requests.

Swoole 4.x uses a brand new engine kernel and now it has a full-time developer team, so we are entering an unprecedented period in PHP history which offers a unique possibility for rapid evolution in performance.

Coroutine

Swoole 4.x or later supports the built-in coroutine with high availability, and you can use fully synchronized code to implement asynchronous performance. PHP code without any additional keywords, the underlying automatic coroutine-scheduling.

Developers can understand coroutines as ultra-lightweight threads, and you can easily create thousands of coroutines in a single process.

MySQL

Concurrency 10K requests to read data from MySQL takes only 0.2s!

$s = microtime(true);
Co\run(function() {
    for ($c = 100; $c--;) {
        go(function () {
            $mysql = new Swoole\Coroutine\MySQL;
            $mysql->connect([
                'host' => '127.0.0.1',
                'user' => 'root',
                'password' => 'root',
                'database' => 'test'
            ]);
            $statement = $mysql->prepare('SELECT * FROM `user`');
            for ($n = 100; $n--;) {
                $result = $statement->execute();
                assert(count($result) > 0);
            }
        });
    }
});
echo 'use ' . (microtime(true) - $s) . ' s';

Mixed server

You can create multiple services on the single event loop: TCP, HTTP, Websocket and HTTP2, and easily handle thousands of requests.

function tcp_pack(string $data): string
{
    return pack('N', strlen($data)) . $data;
}
function tcp_unpack(string $data): string
{
    return substr($data, 4, unpack('N', substr($data, 0, 4))[1]);
}
$tcp_options = [
    'open_length_check' => true,
    'package_length_type' => 'N',
    'package_length_offset' => 0,
    'package_body_offset' => 4
];
$server = new Swoole\WebSocket\Server('127.0.0.1', 9501, SWOOLE_BASE);
$server->set(['open_http2_protocol' => true]);
// http && http2
$server->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response) {
    $response->end('Hello ' . $request->rawcontent());
});
// websocket
$server->on('message', function (Swoole\WebSocket\Server $server, Swoole\WebSocket\Frame $frame) {
    $server->push($frame->fd, 'Hello ' . $frame->data);
});
// tcp
$tcp_server = $server->listen('127.0.0.1', 9502, SWOOLE_TCP);
$tcp_server->set($tcp_options);
$tcp_server->on('receive', function (Swoole\Server $server, int $fd, int $reactor_id, string $data) {
    $server->send($fd, tcp_pack('Hello ' . tcp_unpack($data)));
});
$server->start();

Coroutine clients

Whether you DNS query or send requests or receive responses, all of these are scheduled by coroutine automatically.

go(function () {
    // http
    $http_client = new Swoole\Coroutine\Http\Client('127.0.0.1', 9501);
    assert($http_client->post('/', 'Swoole Http'));
    var_dump($http_client->body);
    // websocket
    $http_client->upgrade('/');
    $http_client->push('Swoole Websocket');
    var_dump($http_client->recv()->data);
});
go(function () {
    // http2
    $http2_client = new Swoole\Coroutine\Http2\Client('localhost', 9501);
    $http2_client->connect();
    $http2_request = new Swoole\Http2\Request;
    $http2_request->method = 'POST';
    $http2_request->data = 'Swoole Http2';
    $http2_client->send($http2_request);
    $http2_response = $http2_client->recv();
    var_dump($http2_response->data);
});
go(function () use ($tcp_options) {
    // tcp
    $tcp_client = new Swoole\Coroutine\Client(SWOOLE_TCP);
    $tcp_client->set($tcp_options);
    $tcp_client->connect('127.0.0.1', 9502);
    $tcp_client->send(tcp_pack('Swoole Tcp'));
    var_dump(tcp_unpack($tcp_client->recv()));
});

Channel

Channel is the only way for exchanging data between coroutines, the development combination of the Coroutine + Channel is the famous CSP programming model.

In Swoole development, Channel is usually used for implementing connection pool or scheduling coroutine concurrent.

The simplest example of a connection pool

In the following example, we have a thousand concurrently requests to redis. Normally, this has exceeded the maximum number of Redis connections setting and will throw a connection exception, but the connection pool based on Channel can perfectly schedule requests. We don't have to worry about connection overload.

class RedisPool
{
    /**@var \Swoole\Coroutine\Channel */
    protected $pool;

    /**
     * RedisPool constructor.
     * @param int $size max connections
     */
    public function __construct(int $size = 100)
    {
        $this->pool = new \Swoole\Coroutine\Channel($size);
        for ($i = 0; $i < $size; $i++) {
            $redis = new \Swoole\Coroutine\Redis();
            $res = $redis->connect('127.0.0.1', 6379);
            if ($res == false) {
                throw new \RuntimeException("failed to connect redis server.");
            } else {
                $this->put($redis);
            }
        }
    }

    public function get(): \Swoole\Coroutine\Redis
    {
        return $this->pool->pop();
    }

    public function put(\Swoole\Coroutine\Redis $redis)
    {
        $this->pool->push($redis);
    }

    public function close(): void
    {
        $this->pool->close();
        $this->pool = null;
    }
}

go(function () {
    $pool = new RedisPool();
    // max concurrency num is more than max connections
    // but it's no problem, channel will help you with scheduling
    for ($c = 0; $c < 1000; $c++) {
        go(function () use ($pool, $c) {
            for ($n = 0; $n < 100; $n++) {
                $redis = $pool->get();
                assert($redis->set("awesome-{$c}-{$n}", 'swoole'));
                assert($redis->get("awesome-{$c}-{$n}") === 'swoole');
                assert($redis->delete("awesome-{$c}-{$n}"));
                $pool->put($redis);
            }
        });
    }
});

Producer and consumers

Some Swoole's clients implement the defer mode for concurrency, but you can still implement it flexible with a combination of coroutines and channels.

go(function () {
    // User: I need you to bring me some information back.
    // Channel: OK! I will be responsible for scheduling.
    $channel = new Swoole\Coroutine\Channel;
    go(function () use ($channel) {
        // Coroutine A: Ok! I will show you the github addr info
        $addr_info = Co::getaddrinfo('github.com');
        $channel->push(['A', json_encode($addr_info, JSON_PRETTY_PRINT)]);
    });
    go(function () use ($channel) {
        // Coroutine B: Ok! I will show you what your code look like
        $mirror = Co::readFile(__FILE__);
        $channel->push(['B', $mirror]);
    });
    go(function () use ($channel) {
        // Coroutine C: Ok! I will show you the date
        $channel->push(['C', date(DATE_W3C)]);
    });
    for ($i = 3; $i--;) {
        list($id, $data) = $channel->pop();
        echo "From {$id}:\n {$data}\n";
    }
    // User: Amazing, I got every information at earliest time!
});

Timer

$id = Swoole\Timer::tick(100, function () {
    echo "⚙️ Do something...\n";
});
Swoole\Timer::after(500, function () use ($id) {
    Swoole\Timer::clear($id);
    echo "⏰ Done\n";
});
Swoole\Timer::after(1000, function () use ($id) {
    if (!Swoole\Timer::exists($id)) {
        echo "✅ All right!\n";
    }
});

The way of coroutine

go(function () {
    $i = 0;
    while (true) {
        Co::sleep(0.1);
        echo "📝 Do something...\n";
        if (++$i === 5) {
            echo "🛎 Done\n";
            break;
        }
    }
    echo "🎉 All right!\n";
});

🔥 Amazing runtime hooks

As of Swoole v4.1.0, we added the ability to transform synchronous PHP network libraries into co-routine libraries using a single line of code.

Simply call the Swoole\Runtime::enableCoroutine() method at the top of your script. In the sample below we connect to php-redis and concurrently read 10k requests in 0.1s:

Swoole\Runtime::enableCoroutine();
$s = microtime(true);
Co\run(function() {
    for ($c = 100; $c--;) {
        go(function () {
            ($redis = new Redis)->connect('127.0.0.1', 6379);
            for ($n = 100; $n--;) {
                assert($redis->get('awesome') === 'swoole');
            }
        });
    }
});
echo 'use ' . (microtime(true) - $s) . ' s';

By calling this method, the Swoole kernel replaces ZendVM stream function pointers. If you use php_stream based extensions, all socket operations can be dynamically converted to be asynchronous IO scheduled by coroutine at runtime!

How many things you can do in 1s?

Sleep 10K times, read, write, check and delete files 10K times, use PDO and MySQLi to communicate with the database 10K times, create a TCP server and multiple clients to communicate with each other 10K times, create a UDP server and multiple clients to communicate with each other 10K times... Everything works well in one process!

Just see what the Swoole brings, just imagine...

Swoole\Runtime::enableCoroutine();
$s = microtime(true);
Co\run(function() {
    // i just want to sleep...
    for ($c = 100; $c--;) {
        go(function () {
            for ($n = 100; $n--;) {
                usleep(1000);
            }
        });
    }

    // 10K file read and write
    for ($c = 100; $c--;) {
        go(function () use ($c) {
            $tmp_filename = "/tmp/test-{$c}.php";
            for ($n = 100; $n--;) {
                $self = file_get_contents(__FILE__);
                file_put_contents($tmp_filename, $self);
                assert(file_get_contents($tmp_filename) === $self);
            }
            unlink($tmp_filename);
        });
    }

    // 10K pdo and mysqli read
    for ($c = 50; $c--;) {
        go(function () {
            $pdo = new PDO('mysql:host=127.0.0.1;dbname=test;charset=utf8', 'root', 'root');
            $statement = $pdo->prepare('SELECT * FROM `user`');
            for ($n = 100; $n--;) {
                $statement->execute();
                assert(count($statement->fetchAll()) > 0);
            }
        });
    }
    for ($c = 50; $c--;) {
        go(function () {
            $mysqli = new Mysqli('127.0.0.1', 'root', 'root', 'test');
            $statement = $mysqli->prepare('SELECT `id` FROM `user`');
            for ($n = 100; $n--;) {
                $statement->bind_result($id);
                $statement->execute();
                $statement->fetch();
                assert($id > 0);
            }
        });
    }

    // php_stream tcp server & client with 12.8K requests in single process
    function tcp_pack(string $data): string
    {
        return pack('n', strlen($data)) . $data;
    }

    function tcp_length(string $head): int
    {
        return unpack('n', $head)[1];
    }

    go(function () {
        $ctx = stream_context_create(['socket' => ['so_reuseaddr' => true, 'backlog' => 128]]);
        $socket = stream_socket_server(
            'tcp://0.0.0.0:9502',
            $errno, $errstr, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $ctx
        );
        if (!$socket) {
            echo "$errstr ($errno)\n";
        } else {
            $i = 0;
            while ($conn = stream_socket_accept($socket, 1)) {
                stream_set_timeout($conn, 5);
                for ($n = 100; $n--;) {
                    $data = fread($conn, tcp_length(fread($conn, 2)));
                    assert($data === "Hello Swoole Server #{$n}!");
                    fwrite($conn, tcp_pack("Hello Swoole Client #{$n}!"));
                }
                if (++$i === 128) {
                    fclose($socket);
                    break;
                }
            }
        }
    });
    for ($c = 128; $c--;) {
        go(function () {
            $fp = stream_socket_client("tcp://127.0.0.1:9502", $errno, $errstr, 1);
            if (!$fp) {
                echo "$errstr ($errno)\n";
            } else {
                stream_set_timeout($fp, 5);
                for ($n = 100; $n--;) {
                    fwrite($fp, tcp_pack("Hello Swoole Server #{$n}!"));
                    $data = fread($fp, tcp_length(fread($fp, 2)));
                    assert($data === "Hello Swoole Client #{$n}!");
                }
                fclose($fp);
            }
        });
    }

    // udp server & client with 12.8K requests in single process
    go(function () {
        $socket = new Swoole\Coroutine\Socket(AF_INET, SOCK_DGRAM, 0);
        $socket->bind('127.0.0.1', 9503);
        $client_map = [];
        for ($c = 128; $c--;) {
            for ($n = 0; $n < 100; $n++) {
                $recv = $socket->recvfrom($peer);
                $client_uid = "{$peer['address']}:{$peer['port']}";
                $id = $client_map[$client_uid] = ($client_map[$client_uid] ?? -1) + 1;
                assert($recv === "Client: Hello #{$id}!");
                $socket->sendto($peer['address'], $peer['port'], "Server: Hello #{$id}!");
            }
        }
        $socket->close();
    });
    for ($c = 128; $c--;) {
        go(function () {
            $fp = stream_socket_client("udp://127.0.0.1:9503", $errno, $errstr, 1);
            if (!$fp) {
                echo "$errstr ($errno)\n";
            } else {
                for ($n = 0; $n < 100; $n++) {
                    fwrite($fp, "Client: Hello #{$n}!");
                    $recv = fread($fp, 1024);
                    list($address, $port) = explode(':', (stream_socket_get_name($fp, true)));
                    assert($address === '127.0.0.1' && (int)$port === 9503);
                    assert($recv === "Server: Hello #{$n}!");
                }
                fclose($fp);
            }
        });
    }
});
echo 'use ' . (microtime(true) - $s) . ' s';

⌛️ Installation

As with any open source project, Swoole always provides the most reliable stability and the most powerful features in the latest released version. Please ensure as much as possible that you are using the latest version.

Compiling requirements

  • Linux, OS X or Cygwin, WSL
  • PHP 7.2.0 or later (The higher the version, the better the performance.)
  • GCC 4.8 or later

1. Install via PECL (beginners)

pecl install openswoole

2. Install from source (recommended)

Please download the source packages from Releases or:

git clone https://github.com/openswoole/swoole-src.git && \
cd swoole-src

Compile and install at the source folder:

phpize && \
./configure && \
make && make install

Enable extension in PHP

After compiling and installing to the system successfully, you have to add a new line extension=openswoole.so to php.ini to enable Swoole extension.

Extra compiler configurations

for example: ./configure --enable-openssl --enable-sockets

  • --enable-openssl or --with-openssl-dir=DIR
  • --enable-sockets
  • --enable-http2
  • --enable-mysqlnd (need mysqlnd, it just for supporting $mysql->escape method)
  • --enable-swoole-json
  • --enable-swoole-curl

Upgrade

⚠️ If you upgrade from source, don't forget to make clean before you upgrade your swoole

  1. pecl upgrade openswoole
  2. cd swoole-src && git pull && make clean && make && sudo make install
  3. if you change your PHP version, please re-run phpize clean && phpize then try to compile

💎 Frameworks & Components

  • Hyperf is a coroutine framework that focuses on hyperspeed and flexibility, specifically used for build microservices or middlewares.
  • Swoft is a modern, high-performance AOP and coroutine PHP framework.
  • Easyswoole is a simple, high-performance PHP framework, based on Swoole, which makes using Swoole as easy as echo "hello world".
  • MixPHP is a powerful single-threaded coroutine framework with a very small footprint, simple and elegant.
  • imi is a high-performance coroutine application development framework based on PHP Swoole, which supports the development of HttpApi, WebSocket, TCP, UDP services.
  • Saber is a human-friendly, high-performance HTTP client component that has almost everything you can imagine.
  • One is a minimalist, high-performance PHP framework that supports the [swoole | php-fpm] environment

🛠 Develop & Discussion

🍭 Benchmark

  • On the open source Techempower Web Framework benchmarks Swoole used MySQL database benchmark to rank first, and all performance tests ranked in the first echelon.
  • You can just run Benchmark Script to quickly test the maximum QPS of Swoole-HTTP-Server on your machine.

🔰️ Security issues

Security issues should be reported privately, via email, to the Swoole develop team [email protected]. You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message.

🖊️ Contribution

Your contribution to Swoole development is very welcome!

You may contribute in the following ways:

❤️ Contributors

This project exists thanks to all the people who contribute. [Contributors].

🎙️ Official Evangelist

Demin has been playing with PHP since 2000, focusing on building high-performance, secure web services. He is an occasional conference speaker on PHP and Swoole, and has been working for companies in the states like eBay, Visa and Glu Mobile for years. You may find Demin on Twitter or GitHub.

📃 License

Apache License Version 2.0 see http://www.apache.org/licenses/LICENSE-2.0.html

Comments
  • Function Server::exist() missing after new installation

    Function Server::exist() missing after new installation

    What did you do? If possible, provide a simple script for reproducing the error.

    I set up a new ubuntu server and migrated my webs to it. Now I get a "PHP Fatal error:  Uncaught Error: Call to undefined method OpenSwoole\WebSocket\Server::exist() " in my Websocket-Scripts. :-( 
    
    What version of OpenSwoole are you using (show your `php --ri openswoole`)?
    
    Open Swoole => enabled
    Author => Open Swoole Group <[email protected]>
    Version => 22.0.0
    Built => Dec 22 2022 13:01:47
    coroutine => enabled with boost asm context
    epoll => enabled
    eventfd => enabled
    signalfd => enabled
    cpu_affinity => enabled
    spinlock => enabled
    rwlock => enabled
    sockets => enabled
    openssl => OpenSSL 3.0.2 15 Mar 2022
    dtls => enabled
    http2 => enabled
    mutex_timedlock => enabled
    pthread_barrier => enabled
    futex => enabled
    mysqlnd => enabled
    postgresql => enabled
    
    Directive => Local Value => Master Value
    openswoole.enable_coroutine => On => On
    openswoole.enable_preemptive_scheduler => Off => Off
    openswoole.display_errors => On => On
    openswoole.unixsock_buffer_size => 8388608 => 8388608
    
    What is your machine environment used (show your `uname -a` & `php -v` & `gcc -v`) ?
    Linux subdomain.domain.com 5.15.0-56-generic #62-Ubuntu SMP Tue Nov 22 19:54:14 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
    
    PHP 8.1.13 (cli) (built: Nov 26 2022 14:07:55) (NTS)
    Copyright (c) The PHP Group
    Zend Engine v4.1.13, Copyright (c) Zend Technologies
        with Zend OPcache v8.1.13, Copyright (c), by Zend Technologies
    
    Using built-in specs.
    COLLECT_GCC=gcc
    COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper
    OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
    OFFLOAD_TARGET_DEFAULT=1
    Target: x86_64-linux-gnu
    Configured with: ../src/configure -v --with-pkgversion='Ubuntu 11.3.0-1ubuntu1~22.04' --with-bugurl=file:///usr/share/doc/gcc-11/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-11 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-11-xKiWfi/gcc-11-11.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-11-xKiWfi/gcc-11-11.3.0/debian/tmp-gcn/usr --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
    Thread model: posix
    Supported LTO compression algorithms: zlib zstd
    gcc version 11.3.0 (Ubuntu 11.3.0-1ubuntu1~22.04) 
    
    opened by tweans 0
  • HTTP Helper functions

    HTTP Helper functions

    1. What did you do? If possible, provide a simple script for reproducing the error.
    
    Copy-paste HTTP helper function script from manual.
    
    <?php
    
    use function OpenSwoole\Coroutine\Http\get;
    
    // Main coroutine context
    co::run(function()
    {
        // Coroutine 1
        go(function()
        {
            $data = get('http://httpbin.org/get?hello=world');
            $body = json_decode($data->getBody());
            assert($body->headers->Host === 'httpbin.org');
            assert($body->args->hello === 'world');
        });
    });
    
    
    
    1. What did you expect to see?
    
    Processed request response.
    
    
    1. What did you see instead?
    PHP Fatal error:  Uncaught Error: Call to undefined function OpenSwoole\Coroutine\Http\get() in Standard input code:12
    
    
    1. What version of OpenSwoole are you using (show your php --ri openswoole)?
    Open Swoole => enabled
    Author => Open Swoole Group <[email protected]>
    Version => 22.0.0
    Built => Dec 28 2022 22:03:58
    coroutine => enabled with boost asm context
    epoll => enabled
    eventfd => enabled
    signalfd => enabled
    cpu_affinity => enabled
    spinlock => enabled
    rwlock => enabled
    sockets => enabled
    openssl => OpenSSL 1.1.1s  1 Nov 2022
    dtls => enabled
    http2 => enabled
    hook-curl => enabled
    pcre => enabled
    zlib => 1.2.13
    mutex_timedlock => enabled
    pthread_barrier => enabled
    futex => enabled
    
    Directive => Local Value => Master Value
    openswoole.enable_coroutine => On => On
    openswoole.enable_preemptive_scheduler => Off => Off
    openswoole.display_errors => On => On
    openswoole.unixsock_buffer_size => 8388608 => 8388608
    
    
    
    1. What is your machine environment used (show your uname -a & php -v & gcc -v) ?
    Linux valkyrie 5.15.72-gentoo-x86_64 #1 SMP Fri Oct 14 11:29:14 AST 2022 x86_64 AMD EPYC 7542 32-Core Processor AuthenticAMD GNU/Linux
    PHP 8.1.12 (cli) (built: Nov 10 2022 17:07:12) (NTS)
    Copyright (c) The PHP Group
    Zend Engine v4.1.12, Copyright (c) Zend Technologies
        with Zend OPcache v8.1.12, Copyright (c), by Zend Technologies
    Using built-in specs.
    COLLECT_GCC=gcc
    COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-pc-linux-gnu/11/lto-wrapper
    Target: x86_64-pc-linux-gnu
    Configured with: /var/tmp/portage/sys-devel/gcc-11.3.1_p20221209/work/gcc-11-20221209/configure --host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/11 --includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/11/include --datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/11 --mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/11/man --infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/11/info --with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/11/include/g++-v11 --with-python-dir=/share/gcc-data/x86_64-pc-linux-gnu/11/python --enable-languages=c,c++,fortran --enable-obsolete --enable-secureplt --disable-werror --with-system-zlib --enable-nls --without-included-gettext --disable-libunwind-exceptions --enable-checking=release --with-bugurl=https://bugs.gentoo.org/ --with-pkgversion='Gentoo 11.3.1_p20221209 p3' --with-gcc-major-version-only --disable-esp --enable-libstdcxx-time --disable-libstdcxx-pch --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --enable-multilib --with-multilib-list=m32,m64 --disable-fixed-point --enable-targets=all --enable-libgomp --disable-libssp --disable-libada --disable-cet --disable-systemtap --disable-valgrind-annotations --disable-vtable-verify --disable-libvtv --without-zstd --enable-lto --without-isl --enable-default-pie --enable-default-ssp
    Thread model: posix
    Supported LTO compression algorithms: zlib
    gcc version 11.3.1 20221209 (Gentoo 11.3.1_p20221209 p3)
    
    
    

    You can also try the following OpenSwoole support channels:

    opened by rootshell-do 0
  • [22.0.0] ZTS build failure

    [22.0.0] ZTS build failure

    In file included from /home/rpmbuild/SPECS/remirepo/php/pecl/php-pecl-openswoole22/openswoole-22.0.0/ext-src/php_swoole_private.h:25,
                     from /home/rpmbuild/SPECS/remirepo/php/pecl/php-pecl-openswoole22/openswoole-22.0.0/ext-src/swoole_atomic.cc:17:
    /home/rpmbuild/SPECS/remirepo/php/pecl/php-pecl-openswoole22/openswoole-22.0.0/ext-src/php_swoole_private.h: In function 'int php_swoole_check_reactor()':
    ./php_openswoole.h:58:22: error: 'openswoole_globals' was not declared in this scope; did you mean 'openswoole_globals_id'?
       58 | #define SWOOLE_G(v) (openswoole_globals.v)
          |                      ^~~~~~~~~~~~~~~~~~
    /home/rpmbuild/SPECS/remirepo/php/pecl/php-pecl-openswoole22/openswoole-22.0.0/ext-src/php_swoole_private.h:1015:9: note: in expansion of macro 'SWOOLE_G'
     1015 |     if (SWOOLE_G(req_status) == PHP_SWOOLE_RSHUTDOWN_BEGIN) {
          |         ^~~~~~~~
    
    
    under review 
    opened by remicollet 0
  • [4.x] properly define function aliasses

    [4.x] properly define function aliasses

    Digging in extension reflection, I notice:

        Method [ <internal:openswoole> public method swoole_timer_list ] {
    
          - Parameters [0] {
          }
          - Return [ <D9>' ]
    
    

    1/ this is obviously not a method 2/ return type is corrupted

    Looking its code, it seems SW_FUNCTION_ALIAS does wrong things.

    This PR drop most usage and use standard API call.

    NOTICE: some usages are still there, perhaps have to be cleaned later:

    ./ext-src/php_swoole.cc:        SW_FUNCTION_ALIAS(CG(function_table), "swoole_coroutine_create", CG(function_table), "go");
    ./ext-src/php_swoole.cc:        SW_FUNCTION_ALIAS(CG(function_table), "swoole_coroutine_defer", CG(function_table), "defer");
    
    ./ext-src/swoole_server.cc:    SW_FUNCTION_ALIAS(&swoole_timer_ce->function_table, "after", &swoole_server_ce->function_table, "after");
    ./ext-src/swoole_server.cc:    SW_FUNCTION_ALIAS(&swoole_timer_ce->function_table, "tick", &swoole_server_ce->function_table, "tick");
    ./ext-src/swoole_server.cc:    SW_FUNCTION_ALIAS(&swoole_timer_ce->function_table, "clear", &swoole_server_ce->function_table, "clearTimer");
    ./ext-src/swoole_server.cc:    SW_FUNCTION_ALIAS(&swoole_event_ce->function_table, "defer", &swoole_server_ce->function_table, "defer");
    
    opened by remicollet 3
  • Random got WARNING ProcessPool::wait(): worker#1 abnormal exit, status=0, signal=13

    Random got WARNING ProcessPool::wait(): worker#1 abnormal exit, status=0, signal=13

    1. What did you do? If possible, provide a simple script for reproducing the error.

    I made local server based on standart alpine docker images https://hub.docker.com/r/shlinkio/shlink and https://hub.docker.com/r/shlinkio/shlink-web-client

    When setting and starting up with docker-compose.yml absolutely randomly I gеt errors "connection refused" when try API/redirect requests or "502 bad gateway" when use nginx proxy_pass to shlink docker container.

    I tried several configs with docker compose with mysql/maria, rabbit, geolite, web_worker_num, task_worker_num, domain, base path - but nothing does matters.

    I check logs in shlinks docker container, when get the error: WARNING ProcessPool::wait(): worker#1 abnormal exit, status=0, signal=13

    I dont understand what happens. I think OpenSwoole breaks the requests.

    1. What did you expect to see? no errors and correctly working docker container

    2. What did you see instead? failed requests with error in logs, that I describe earlier

    3. What version of OpenSwoole are you using (show your php --ri openswoole)?

    /etc/shlink # php --ri openswoole
    
    openswoole
    Open Swoole => enabled
    Author => Open Swoole Group <[email protected]>
    Version => 4.11.1
    Built => Oct 18 2022 17:12:42
    coroutine => enabled with boost asm context
    epoll => enabled
    eventfd => enabled
    signalfd => enabled
    spinlock => enabled
    rwlock => enabled
    mutex_timedlock => enabled
    pthread_barrier => enabled
    async_redis => enabled
    
    Directive => Local Value => Master Value
    swoole.enable_coroutine => On => On
    swoole.enable_library => On => On
    swoole.enable_preemptive_scheduler => Off => Off
    swoole.display_errors => On => On
    swoole.use_shortname => On => On
    swoole.unixsock_buffer_size => 8388608 => 8388608
    
    1. What is your machine environment used (show your uname -a & php -v & gcc -v) ?

    DOCKER CONTAINER SHLINK

    /etc/shlink # uname -a
    Linux f0e141b14fed 5.10.16.3-microsoft-standard-WSL2 #1 SMP Fri Apr 2 22:23:49 UTC 2021 x86_64 Linux
    
    /etc/shlink # php -v
    PHP 8.1.9 (cli) (built: Aug  9 2022 21:47:49) (NTS)
    Copyright (c) The PHP Group
    Zend Engine v4.1.9, Copyright (c) Zend Technologies
    
    /etc/shlink # gcc -v
    /bin/sh: gcc: not found
    

    MY HOST MACHINE

    Windows 10 Pro 21H1 64bit, DDR4 48GB, Xeon E5-2678 3.3GHz
    Docker Desktop v4.13.1 with WSL2 (config VM memory=32GB processors=20) 
    on Ubuntu 20.04.5 LTS (GNU/Linux 5.10.16.3-microsoft-standard-WSL2 x86_64)
    
    [email protected]:~# uname -a
    Linux slava-pc 5.10.16.3-microsoft-standard-WSL2 #1 SMP Fri Apr 2 22:23:49 UTC 2021 x86_64 GNU/Linux
    

    DOCKER-COMPOSE.YML

    db:
    	container_name: my-db
    	image: mariadb:10.3.34
    	restart: always
    	ports:
    		- '127.0.0.1:3306:3306'
    	command: [
    		'--default-authentication-plugin=mysql_native_password',
    		'--character-set-server=utf8',
    		'--collation-server=utf8_unicode_ci'
    	]
    	environment:
    		MYSQL_ROOT_PASSWORD: password
    		TZ: Europe/Berlin
    	volumes:
    		- my-db-data:/var/lib/mysql
    
    shlink:
    	container_name: my-shlink
    	image: shlinkio/shlink:3.3.2
    	restart: always
    	environment:
    		DEFAULT_DOMAIN: shlink.local
    		PORT: 8080
    		BASE_PATH: /shlink
    		IS_HTTPS_ENABLED: false
    		WEB_WORKER_NUM: 8
    		TASK_WORKER_NUM: 8
    		INITIAL_API_KEY: shlinkapikey
    		DB_DRIVER: maria
    		DB_NAME: shlink
    		DB_USER: root
    		DB_PASSWORD: password
    		DB_HOST: my-db
    		GEOLITE_LICENSE_KEY: ${SHLINK_GEOLITE_LICENSE_KEY}
    		SKIP_INITIAL_GEOLITE_DOWNLOAD: false
    		ENABLE_PERIODIC_VISIT_LOCATE: false
    	links:
    		- db
    	depends_on:
    		- db
    	ports:
    		- '127.0.0.1:8080:8080'
    
    shlinkweb:
    	container_name: my-shlinkweb
    	image: shlinkio/shlink-web-client
    	restart: always
    	volumes:
    		- ./docker/dev/shlink/servers.json:/usr/share/nginx/html/servers.json
    	links:
    		- shlink
    	depends_on:
    		- shlink
    	ports:
    		- '127.0.0.1:8000:80'
    

    SERVER.JSON file

    [
        {
            "name": "Localhost",
            "url": "http://shlink.local/shlink",
            "apiKey": "shlinkapikey"
        }
    ]
    
    under review 
    opened by slava-o 0
Releases(v22.0.0)
  • v22.0.0(Dec 21, 2022)

     . Rename `co\run` to be `co::run`
     . Security update: Remove embedded PHP codes, hot code execution with eval and remove `ini` option `enable_library`
     . Added server Constants class: OpenSwoole\Constant
     . Use \OpenSwoole as the main namespace, although \Swoole is still supported
     . Pre-check server options
     . Security update: New server option `enable_server_token`, disabled by default
     . Built-in Psr7 API support added
     . Boost ASM library upgrade
     . New Psr API: $server->setHandler(\Psr\Http\Server\RequestHandlerInterface $handler)
     . New Psr API: $server->handle(callable $callback)
     . Redis Server API: $server->setHandler() -> $server->addCommand()
     . Redis Server API: $server->getHandler() -> $server->getCommand()
     . Disable sockets_*, exec, shell_exec, `gethostbyname` coroutines hook by default, remove HOOK_BLOCKING_FUNCTION and HOOK_SOCKETS in HOOK_ALL; Enable them explicitly if they are used
     . Remove deprecated custom coroutine MySQL client, prefer the hooked native coroutine MySQL client
     . Remove deprecated custom coroutine Redis client, prefer the hooked native coroutine Redis client
     . Remove deprecated experimental coroutine HTTP server
     . Remove deprecated experimental Redis protocol server
     . Remove deprecated function `swoole_timer_set()` and `Timer->set()`
     . Remove deprecated function `swoole_event_rshutdown`
     . Remove deprecated function `Swoole\Runtime::fread`, `Swoole\Runtime::fwrite`, `Swoole\Runtime::fgets`
     . Remove deprecated function `Coroutine::suspend`, use `Coroutine::yield`
     . Remove deprecated function `Coroutine::getuid`, use `Coroutine::getCid`
     . Remove deprecated function `Coroutine::listCoroutines`, use `Coroutine::list`
     . Remove deprecated function `Table::exist`, use `Table::exists`
     . Remove deprecated function `Table::delete`, use `Table::del`
     . Remove deprecated function `Server->connection_info()`, use `Server->getClientInfo()`
     . Remove deprecated function `Server->connection_list()`, use `Server->getClientList()`
     . Remove deprecated function `Server->exist`, use `Server->exists`
     . Move global constants under namespace: SWOOLE_CHANNEL_OK -> `OpenSwoole\Coroutine\Channel::CHANNEL_OK`, SWOOLE_CHANNEL_TIMEOUT -> `OpenSwoole\Coroutine\Channel::CHANNEL_TIMEOUT`, SWOOLE_CHANNEL_CLOSED -> `OpenSwoole\Coroutine\Channel::CHANNEL_CLOSED`...
     . Move global constants under namespace: SWOOLE_DEFAULT_MAX_CORO_NUM -> `OpenSwoole\Coroutine::DEFAULT_MAX_CORO_NUM`...
     . Remove `$server->getLastError()`, use `OpenSwoole\Util::getLastErrorCode()`
     . Remove `$process->name()`, use `OpenSwoole\Util::setProcessName()`
     . New Util API class: added `OpenSwoole\Util` class
     . Remove option `swoole.use_shortname`, remove `Co\*` alias. `go`, `chan`, `defer`, `co::*` are available by default
     . Remove `swoole_async_dns_lookup_coro`, use `OpenSwoole\Coroutine::dnsLookup` or `OpenSwoole\Coroutine\System::dnsLookup`; remove `swoole_async_set`, use `OpenSwoole\Until::setAio([])` or `$server->set([])` for `aio` options;
     . Rename PHP `ini` options from `swoole.*` to be `openswoole.*`
     . Remove `swoole_clear_dns_cache`, use OpenSwoole\Coroutine::clearDNSCache` or `OpenSwoole\Coroutine\System::clearDNSCache`
     . Remove custom unserialize functions: `swoole_substr_unserialize` and `swoole_substr_unserialize`
     . Remove `swoole_client_select` and `swoole_select`, use `OpenSwoole\Client::select`
     . Remove `swoole_last_error`, use `OpenSwoole\Util::getLastErrorCode`
     . `OpenSwoole\Event::wait();` should be added explicitly to wait for all the IO events
     . Use `\OpenSwoole\Server::SIMPLE_MODE` and `\OpenSwoole\Server::POOL_MODE` at server structure config
     . Fix: ignore user set illegal HTTP header at server
     . Fix: ignore user set encoding header at client if it is not supported
     . Remove hard requirements and links of json and remove compile flag `--enable-swoole-json`
     . Rename compile flag `--enable-swoole-curl` to be `--enable-hook-curl`
     . Fix convert double sec to long microseconds in hooked usleep by @shandyDev
    
    Source code(tar.gz)
    Source code(zip)
  • v4.12.1(Dec 21, 2022)

  • v4.12.0(Oct 2, 2022)

  • v4.11.1(Apr 28, 2022)

  • v4.11.0(Mar 22, 2022)

    . New feature: support http_index_files at HTTP2 server . HTTP2: allow HTTP2 client and server to set custom HTTP2 settings . Support static compile . CI: Remove PHP7.2/7.3 support as they are not supported by the PHP team . Bug fixed: Fix HTTP2 client and respect max_concurrent_streams settings . HTTP2: Update HTTP2 default max concurrent streams per connection to be 1280 . Bug fixed: Respect server side settings at HTTP2 client . Optimize signal-driven timer code (@hauptmedia) . Bug fixed: $server->getWorkerPid does not return the correct worker pid when being called from another worker context . Bug fixed: init window size in http2 server . Deprecated: redis server . Bug fixed: close HTTP2 connection when there are errors . Close connection when a process is stopped and it is managing http2 sessions . Bug fixed: fix user land timer is not stopping when the server is shutting down . Postgres client: return empty array if the result set is empty . Postgres client: provide constant enums for $connection->resultStatus . Postgres client: added new API $pg->reset() and $pg->status() (@RedChops) . CI and tests: fixed many many bugs in tests and improved the CI and testing (@hauptmedia) . Build fix for gcc < 4.9 (@dmz-uk)

    Source code(tar.gz)
    Source code(zip)
    openswoole-cygwin-v4.11.0.zip(45.18 MB)
  • v4.10.0(Jan 24, 2022)

  • v4.9.1(Dec 26, 2021)

  • v4.9.0(Dec 19, 2021)

  • v4.8.1(Nov 29, 2021)

  • v4.8.0(Nov 23, 2021)

    🎉 Thanks the contributors in this release: @Hailong @leocavalcante @weierophinney @remicollet @alexander-schranz 🎉

    • Official PHP 8.1 stable support
    • Native support for postgres coroutine client, enable --with-postgres[=DIR]
    • New HTTP server option: max_request_execution_time
    • Support strict type hinting and fix the type of arguments, return value
    • Bug fixed: data loss bug in Swoole table
    • Bug fixed: compile issues when enable openssl on MacOS
    • Throw \Swoole\Exception when Swoole table is too small to avoid data loss
    • Deprecation warning added: Swoole\Coroutine\Server
    • Deprecation warning added: Swoole\Coroutine\Barrier
    • Deprecation warning added: Swoole\Coroutine\Http\Server
    • Deprecation warning added: SWOOLE_HOOK_CURL, use SWOOLE_HOOK_NATIVE_CURL
    Source code(tar.gz)
    Source code(zip)
    openswoole-cygwin-v4.8.0.zip(44.40 MB)
  • v4.7.2(Oct 24, 2021)

    1. Extension name changed to be openswoole
    2. Bug fixed: PHP8.0 compatible issues
    3. Bug fixed: PHP8.0 and Symfony HTTP client, Guzzle compatible issues
    4. Added SW_ERROR_WEBSOCKET_PACK_FAILED error code
    5. Updated Server id to be OpenSwoole-v4.x.x, Client id to be OpenSwoole/v4.x.x
    6. Bug fixed: HTTP2 flow control bugs
    7. Support ssl_ciphers in Swoole Client
    8. Bug fixed: curl_multi_select CURL_SOCKET_TIMEOUT bug
    9. Bug fixed: openswoole_postgresql compile issues on MacOS
    Source code(tar.gz)
    Source code(zip)
    openswoole-cygwin-v4.7.2.zip(44.39 MB)
    swoole-cygwin-v4.7.2.zip(44.45 MB)
  • v4.7.1(Oct 17, 2021)

    New feature

    • Introduce a new concurrency mode (#4330) (@doubaokun)

    Enhancement

    • Supported query /etc/hosts for System::dnsLookup (#4341) (#4349) (@zmyWL) (@NathanFreeman)
    • Supported boost context support for mips64 (#4358) (@dixyes)
    • Supported CURLOPT_RESOLVE option for SWOOLE_HOOK_CURL (swoole/library#107) (@sy-records)
    • Supported CURLOPT_NOPROGRESS for SWOOLE_HOOK_CURL (swoole/library#117) (@sy-records)
    • Supported boost context support for riscv64 (#4375) (@dixyes)

    Fixed

    • Fixed memory error on shutdown (PHP-8.1) (#4325) (@twose)
    • Fixed not serializable classes for 8.1.0beta1 (#4335) (@remicollet)
    • Fixed multiple coroutines recursively creating directories (#4337) (@NathanFreeman)
    • Fixed native curl bugs (#4360) (@matyhtf)
    • Fixed PDOStatement::bindParam() expects parameter 1 to be string (swoole/library#116) (@sy-records)
    Source code(tar.gz)
    Source code(zip)
Owner
Open Swoole
Open source PHP extension for Async IO, Coroutines and Fibers
Open Swoole
C++14 asynchronous allocation aware futures (supporting then, exception handling, coroutines and connections)

Continuable is a C++14 library that provides full support for: lazy async continuation chaining based on callbacks (then) and expression templates, ca

Denis Blank 771 Dec 20, 2022
C++20 coroutines-based cooperative multitasking library

?? Coop Coop is a C++20 coroutines-based library to support cooperative multitasking in the context of a multithreaded application. The syntax will be

Jeremy Ong 81 Dec 9, 2022
Discrete-event simulation in C++20 using coroutines

SimCpp20 SimCpp20 is a discrete-event simulation framework for C++20. It is similar to SimPy and aims to be easy to set up and use. Processes are defi

Felix Schütz 34 Nov 15, 2022
Header-Only C++20 Coroutines library

CPP20Coroutines Header-Only C++20 Coroutines library This repository aims to demonstrate the capabilities of C++20 coroutines. generator Generates val

null 16 Aug 15, 2022
Cppcoro - A library of C++ coroutine abstractions for the coroutines TS

CppCoro - A coroutine library for C++ The 'cppcoro' library provides a large set of general-purpose primitives for making use of the coroutines TS pro

Lewis Baker 2.6k Dec 30, 2022
Coro - Single-header library facilities for C++2a Coroutines

coro This is a collection of single-header library facilities for C++2a Coroutines. coro/include/ co_future.h Provides co_future<T>, which is like std

Arthur O'Dwyer 66 Dec 6, 2022
Async++ concurrency framework for C++11

Async++ Async++ is a lightweight concurrency framework for C++11. The concept was inspired by the Microsoft PPL library and the N3428 C++ standard pro

Amanieu d'Antras 1.1k Dec 30, 2022
Async GRPC with C++20 coroutine support

agrpc Build an elegant GRPC async interface with C++20 coroutine and libunifex (target for C++23 executor). Get started mkdir build && cd build conan

Yuchao Zhang 65 Dec 21, 2022
Open source re-creation of the copenheimer project.

openheimer Open source re-creation of the copenheimer project. Stage 1: Completed! - Make a extremely fast minecraft server scanner that does the hand

null 28 Dec 14, 2022
Open MPI main development repository

Open MPI The Open MPI Project is an open source Message Passing Interface (MPI) implementation that is developed and maintained by a consortium of aca

Open MPI 1.6k Jan 5, 2023
Kernel source code of EZ-FLASH OMEGA Definitive Edition

#EZ-FLASH Omega Definitive Edition Kernel How to build 1.We use devkitARM_r53, you can use the current version or newer. 2.Set the following environme

null 38 Nov 29, 2022
Concurrency Kit 2.1k Jan 4, 2023
An implementation of Actor, Publish-Subscribe, and CSP models in one rather small C++ framework. With performance, quality, and stability proved by years in the production.

What is SObjectizer? What distinguishes SObjectizer? SObjectizer is not like TBB, taskflow or HPX Show me the code! HelloWorld example Ping-Pong examp

Stiffstream 314 Dec 26, 2022
Simple and fast C library implementing a thread-safe API to manage hash-tables, linked lists, lock-free ring buffers and queues

libhl C library implementing a set of APIs to efficiently manage some basic data structures such as : hashtables, linked lists, queues, trees, ringbuf

Andrea Guzzo 392 Dec 3, 2022
Sqrt OS is a simulation of an OS scheduler and memory manager using different scheduling algorithms including Highest Priority First (non-preemptive), Shortest Remaining Time Next, and Round Robin

A CPU scheduler determines an order for the execution of its scheduled processes; it decides which process will run according to a certain data structure that keeps track of the processes in the system and their status.

null 10 Sep 7, 2022
RocketOS is a Unix based OS that uses legacy BIOS and GRUB and is written in C17. It is being developed for educational purposes primarily, but it still is a serious project. It is currently in its infancy.

RocketOS What is RocketOS? RocketOS is a Unix based OS that uses legacy BIOS and GRUB and is written in C17. It is being developed for educational pur

null 30 Sep 19, 2022
Suman Raj Khanal 7 Nov 24, 2021
OOX: Out-of-Order Executor library. Yet another approach to efficient and scalable tasking API and task scheduling.

OOX Out-of-Order Executor library. Yet another approach to efficient and scalable tasking API and task scheduling. Try it Requirements: Install cmake,

Intel Corporation 18 Oct 25, 2022