workerman icon indicating copy to clipboard operation
workerman copied to clipboard

about php 8.1 based fiber support in Workerman

Open raghuveer opened this issue 2 years ago • 25 comments

Hi,

As php 8.1 is public few weeks earlier, any plan to support fiber implementation in php 8.1?

https://wiki.php.net/rfc/fibers

please share your inputs

thank you

raghuveer avatar Dec 16 '21 17:12 raghuveer

This month, workman will create a V5 branch and supports revoltphp/event-loop which supports fiber.

walkor avatar Dec 17 '21 02:12 walkor

Awesome Walkor, I wanted to ask if revoltphp's event loop will be supported and not sure about your views, so, posted in generic way.

Thank you for the update and this means, we can use amphp, reactphp libraries even when trying workerman, after revoltphp event loop is integration is made available

raghuveer avatar Dec 17 '21 04:12 raghuveer

I wanted to ask if revoltphp's event loop will be supported

Yes, workerman v5 will supports revoltphp's event loop. So we can use amphp, reactphp libraries in workerman v5.

walkor avatar Dec 17 '21 04:12 walkor

PHP coroutine framework https://github.com/wind-framework/wind-framework/tree/1.0 1.0-dev is already adapter with revoltphp, it's base on workerman, I'm excited to wait for V5 version that for wind framework.

xpader avatar Dec 19 '21 15:12 xpader

@xpader, it's nice to know, the ecosystem to grow with more and more options, All the Best :)

raghuveer avatar Dec 20 '21 02:12 raghuveer

This month, workman will create a V5 branch and supports revoltphp/event-loop which supports fiber.

Is v5 production ready? Does it support coroutines in any way?

cayolblake avatar Feb 24 '22 01:02 cayolblake

Workerman v5 branch already supports revoltphp/event-loop which support coroutines. Workerman v5 not released and trying to wait revoltphp/event-loop's first stable LTS release.

walkor avatar Feb 24 '22 02:02 walkor

That's good to hear.

I also checked README.md on the v5 branch and couldn't find any additional information on the usage of the event-loop or how to create a coroutine.

If you can create a working example that would be great.

cayolblake avatar Feb 24 '22 07:02 cayolblake

revoltphp/event-loop use EventLoop::getSuspension(); create a fiber coroutine. We can suspend it or resume it at any time. In most cases, we do not need to call the coroutine api. Frameworks or components will help us do these things when needed.

walkor avatar Feb 24 '22 08:02 walkor

Is it possible you could create an example code using workerman v5 and creating a coroutine?

Thank would be really helpful. I can open a different issue if that will be more appropriate :)

cayolblake avatar Feb 24 '22 15:02 cayolblake

<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
Worker::$eventLoopClass = 'Workerman\Events\Revolt';
$worker = new Worker('http://0.0.0.0:12345');
$worker->onMessage = function($connection, $request)
{
    // Synchronous code but asynchronous non blocking execution
    $response = get('http://example.com');
    $connection->send($response);
};

function get($url) {
    static $http;
    $http = $http ?: new Workerman\Http\Client();
    $event_loop = Worker::getEventLoop()->driver();
    // Create fiber
    $suspension = $event_loop->getSuspension();
    $http->get($url, function($response) use ($suspension){
        // Resume fiber
        return $suspension->resume($response);
    });
    // Suspend fiber
    return $suspension->suspend();
}

Worker::runAll();

With fiber, we can write asynchronous non blocking code in synchronous mode. When workerman V5 released, workerman/http-client library will support fiber from the lower layer without users' manual call. At that time, the api is likely to be like this.

<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
Worker::$eventLoopClass = 'Workerman\Events\Revolt';
$worker = new Worker('http://0.0.0.0:12345');
$worker->onMessage = function($connection, $request)
{
    $http = new Workerman\Http\Client();
    $response = $http ->get('http://example.com');
    $connection->send($response);
};

Worker::runAll();

walkor avatar Feb 25 '22 02:02 walkor

That's great. Thanks for the sample code.

Is there a way to execute for example some heavy image processing code or a database query inside a coroutine? not just network requests.

For example, in Laravel Octane when depending on Swoole, I could create a coroutine in the following syntax.

        [ $var_a, $var_b ] = Octane::concurrently( [
            fn() => $this->heavy_db_function_a( $param ),
            fn() => $this->heavy_db_function_b( $param )
        ] );

Is it possible to run anything inside a coroutine?

cayolblake avatar Feb 25 '22 07:02 cayolblake

At present, revoltphp/event-loop not provide such interface.

walkor avatar Feb 25 '22 09:02 walkor

I'm new to all of this, but, I just checked https://revolt.run/fibers and guess I can place a database query in a suspend-able function !? 🤔

I did not try that yet, I will try to do so but if I'm looking at this the wrong way please enlighten me.

Also, as a side note, I am getting version errors when trying to install workerman/http-client with workerman ^5.x-dev so not sure if there's a specific way for installation.

I highly appreciate your rapid responses btw. It means a lot to the community 👍 👏

cayolblake avatar Feb 25 '22 10:02 cayolblake

I am getting version errors when trying to install workerman/http-client with workerman ^5.x-dev so not sure if there's a specific way for installation.

When I install workerman/http-client I manually changed workerman to ^4.0.

I think when you using db library which support revoltphp/event-loop the codes below are the same effect.

[ $var_a, $var_b ] = Octane::concurrently( [
      fn() => $this->heavy_db_function_a( $param ),
      fn() => $this->heavy_db_function_b( $param )
  ] );
$var_a = $this->heavy_db_function_a( $param );
$var_b = $this->heavy_db_function_b( $param );

walkor avatar Feb 25 '22 11:02 walkor

In the same process, swoole and fiber not will not really execute code in parallel. From a certain point of view, they are still serial, but they are scheduled to execute other code when encountering IO calls.

walkor avatar Feb 25 '22 11:02 walkor

In the same process, swoole and fiber not will not really execute code in parallel. From a certain point of view, they are still serial, but they are scheduled to execute other code when encountering IO calls.

Yeah, I kinda get that. The reason I want to use this is because I have a number of heavy IO operations, some independent of each other and could benefit from (virtually) parallel execution.

When I install workerman/http-client I manually changed workerman to ^4.0.

I assumed you can't use revoltphp/event-loop with ^4.0 🤔

I think when you using db library which support revoltphp/event-loop the codes below are the same effect.

No I don't have a db library supporting revolt. I was talking about normal db query execution through any modern orm library. Do I have to have a special db library to do so ?! This is confusing 😕

cayolblake avatar Feb 25 '22 11:02 cayolblake

I assumed you can't use revoltphp/event-loop with ^4.0

Yes, composer info show revolt/event-loop v0.2.2

No I don't have a db library supporting revolt. I was talking about normal db query execution through any modern orm library. Do I have to have a special db library to do so ?! This is confusing

Finer can not (virtually) parallel execution normal db query through modern orm library. If you want all IO to be executed concurrently through fiber, you need to rewrite all IO clients to support fiber, which is a very arduous task. However, swoole basically realizes all IO concurrent execution through low-level hook. At present, swoole collaboration is the best practice. Workerman v5 will supports swoole too.

walkor avatar Feb 25 '22 12:02 walkor

What is meant Workerman v5 will supports swoole too ?

I assumed workerman is a replacement for swoole! How can they collaborate?

cayolblake avatar Feb 25 '22 12:02 cayolblake

Swoole is also an event-loop so workerman can use it .

walkor avatar Feb 25 '22 13:02 walkor

Okay, but, isn't Swoole only working through its own socket framework? Be it http or tcp or whatever implementation you're using!? 🤔

cayolblake avatar Feb 25 '22 15:02 cayolblake

Stable version of revoltphp is released https://twitter.com/revoltphp/status/1588247750038106112?s=20&t=5y2nGmjJej3ufWF2iVs-YA

Workerman v5 branch already supports revoltphp/event-loop which support coroutines. Workerman v5 not released and trying to wait revoltphp/event-loop's first stable LTS release.

raghuveer avatar Nov 14 '22 06:11 raghuveer

When we can expect Workerman 5.0 live, based upon stable version of revoltphp @walkor

raghuveer avatar Nov 25 '22 05:11 raghuveer

V5 requires a lot of testing, at least 2 months.

walkor avatar Nov 25 '22 06:11 walkor

it will be worth it :)

raghuveer avatar Nov 25 '22 07:11 raghuveer