swoole / swoole-src

🚀 Coroutine-based concurrency library for PHP
https://www.swoole.com
Apache License 2.0
18.42k stars 3.16k forks source link

Don't wait for code to execute #3772

Closed evonicgu closed 3 years ago

evonicgu commented 3 years ago

I want to have some long executing code to be executed after the result is returned. For example, I have a controller method that updates my DB. It must start the DB transaction and return the response immediately without waiting for the transaction to end. Is there any way to do this (not only with DB operations)?

Yurunsoft commented 3 years ago
$http = new Swoole\Http\Server("127.0.0.1", 9501);
$http->on('request', function ($request, $response) {
    $response->end("<h1>Hello Swoole. #".rand(1000, 9999)."</h1>");
    // create new coroutine
    go(function(){
        // do something
    });
});
$http->start();
evonicgu commented 3 years ago

The code is in my controller, that must return a \Psr\Http\ResponseInterface instance. I cannot use \Swoole\Http\Response::end() method.

Yurunsoft commented 3 years ago

The code is just an example, you can create a coroutine before return Or you can use \Swoole\Coroutine::defer(function(){/* do something */});

evonicgu commented 3 years ago

But if I create a coroutine I have to wait for it to execute. For example:

...
// create context and execute coroutine
Co\run(static function () {
    Co::sleep(1);
});
// return will happen after 1sec
return 1;
Yurunsoft commented 3 years ago

You need to use Swoole\Coroutine::create() or go()

evonicgu commented 3 years ago

And why is Co\run used everywhere in the documentation?

Yurunsoft commented 3 years ago

Co\run is designed to replace the patten go() + Swoole\Event::wait() as a context for executing coroutines.

https://www.swoole.co.uk/docs/modules/swoole-coroutine-create https://www.swoole.co.uk/docs/modules/swoole-coroutine-run

evonicgu commented 3 years ago

So, it creates a coroutine context, which is created by Swoole HTTP Server. Am i right?

Yurunsoft commented 3 years ago

Co\run will wait for the coroutine to finish executing. If you don’t need to wait for the execution of the coroutine, you can use Swoole\Coroutine::create().

evonicgu commented 3 years ago

Ok, thanks :)