walkor / workerman

An asynchronous event driven PHP socket framework. Supports HTTP, Websocket, SSL and other custom protocols.
http://www.workerman.net
MIT License
11.17k stars 2.27k forks source link

about php 8.1 based fiber support in Workerman #693

Open raghuveer opened 2 years ago

raghuveer commented 2 years ago

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

walkor commented 2 years ago

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

raghuveer commented 2 years ago

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

walkor commented 2 years ago

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.

xpader commented 2 years ago

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.

raghuveer commented 2 years ago

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

cayolblake commented 2 years ago

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?

walkor commented 2 years ago

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.

cayolblake commented 2 years ago

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.

walkor commented 2 years ago

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.

cayolblake commented 2 years ago

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 :)

walkor commented 2 years ago
<?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();
cayolblake commented 2 years ago

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?

walkor commented 2 years ago

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

cayolblake commented 2 years ago

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 👍 👏

walkor commented 2 years ago

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 commented 2 years ago

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.

cayolblake commented 2 years ago

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 😕

walkor commented 2 years ago

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.

cayolblake commented 2 years ago

What is meant Workerman v5 will supports swoole too ?

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

walkor commented 2 years ago

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

cayolblake commented 2 years ago

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

raghuveer commented 2 years ago

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 commented 1 year ago

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

walkor commented 1 year ago

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

raghuveer commented 1 year ago

it will be worth it :)