reactphp / reactphp

Event-driven, non-blocking I/O with PHP.

Home Page:https://reactphp.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Async promise not really async

imdad opened this issue · comments

Please refer to the below code

$i = 0;
$loop = \React\EventLoop\Factory::create();
$deferred = new \React\Promise\Deferred();

$deferredSubTask = [];
$doSubtask = function ($i) use (&$deferredSubTask) {
    echo "Resolving subtask ", $i, PHP_EOL;
    $deferredSubTask[$i]->resolve();
    echo "Resolved subtask ", $i, PHP_EOL;
};

$timer = $loop->addPeriodicTimer(0.05, function (\React\EventLoop\Timer\Timer $timer) use (&$i, $deferred) {
    global $doSubtask;
    $deferred->notify($i);
    $doSubtask($i);

    $i++;
    if ($i >= 10) {
        $timer->cancel();
        $deferred->resolve();
    }
});

$deferred->promise()->then(function ($i) {
    echo 'Done all tasks!', PHP_EOL;

    return $i;

}, null, function ($i) use (&$deferredSubTask) {
    echo PHP_EOL, 'Main task ', $i, PHP_EOL;
    $deferredSubTask[$i] = new \React\Promise\Deferred();

    $deferredSubTask[$i]->promise()->then(function ($i) {
        echo "Starting Subtask ", $i, PHP_EOL;
        sleep(1);
        echo "Finished subtask $i", PHP_EOL;
        return "Inner : " . $i;

    }, null, null);

    return $i;
});

$loop->run();

Basically I am running a periodic timer and running a main task for 10 times (i.e. from 0 to 9). For each main task there is a sub task. I have used promise to keep the main tasks get started one after other without waiting for the corresponding sub-task to get finished. But, it waits for the sub task to get finished then only starts the next main task. This works synchronously so, I'm not getting any benefit of using promise as I could write synchronous style code without using reactPHP. What changes I need to make in my code so that the main tasks will not have to wait for the sub tasks to get finished.

Thanks in advance
SK Imdad

Hey @imdad, first of all using Promises and ReactPHP doesn't making something magically async. Secondly ReactPHP is single threaded so if you block the loop with a sleep() it will block everything. So if you run a task in the main thread that is blocking you might want to my it out using child processes alternatively you can use my pool package, even in combination with closure child to make it a bit easier for you.

I believe this has been answered, so I'm closing this for now. Please come back with more details if this problem persists and we can reopen this 👍