I am trying to achieve a parallel execution of my workers and I'm using ReactPHP
to help me. https://github.com/reactphp/react
But I'm not getting behaviour that I'm expecting to get.
Scenario:
I have three workers.
fetch.php
parse.php
notify.php
fetch.php
and notify.php
don't have prerequired conditions to run, so they can run in parallel and should run first.
parse.php
needs to wait for fetch.php
to finish with work and then it should execute.
So i have my parent script process.php
where all the magic happens.
$tasks = ['fetch', 'notify'];
forkProcess($tasks);
function forkProcess($tasks)
{
if (empty($tasks)) return false;
$loop = React\EventLoop\Factory::create();
foreach ($tasks as $task) {
$process = new React\ChildProcess\Process("php $task.php");
$loop->addTimer(0.001, function($timer) use ($process, $task) {
$process->start($timer->getLoop());
$process->stdout->on('data', function($output) use ($task) {
echo $output;
$subTasks = getDependentTask($task);
forkProcess($subTasks);
});
});
}
$loop->run();
}
function getDependentTask($task)
{
if ($task != 'fetch') return [];
return [
'parse'
];
}
So instead of getting this output:
FETCH
NOTIFY
PARSE
I am getting
FETCH
PARSE
NOTIFY
And script waits for parsing to finish and then goes to the next task which is notify.
So I am doing something wrong and since I'm playing around with ReactPHP for the first time its probably some rookie mistake.
Is the problem that I'm using recursion and that is blocking the loop or something else.
Maybe loop was not implemented to solve this kind of problems that I'm trying to solve?
I got it.
Problem is with recursion.
See in my first task fetch i have just a echo 'FETCH';
And it's instant so it gets data immediately and it enters .on('data') event and calls function again with new array. So that is a design problem that I'm having.
Figured it out immediately after i posted this question.
If i edit my fetch.php
worker and set sleep(1)
before echo
i get notify worker to output string first.