I have a server long time running application which store process like this:
routes.php
Route::post('cloud/slice/{modelfileid}', 'CloudController@slice');
Route::get('cloud/slice/sliceProgress', 'CloudController@sliceProgress');
part of slice() function:
while($s = fgets($pipes[2]))
{
if(strpos($s, "Progress:") !== FALSE)
{
Log::info(100 * substr($s, -10, 4) . '%');
$this->redis->SET('sliceProgress' . $uid, 100 * substr($s, -10, 4) . '%');
}
}
and my client every 0.5 second request the progress in the redis with this:
public function sliceProgress()
{
if (!isset($_SESSION["uid"]))
return Redirect::to('cloud');
$uid = $_SESSION["uid"];
return Response::json(array('status' => 'success', 'data' => array('progress' => $this->redis->GET('sliceProgress' . $uid))));
}
and
$interval(function()
{
$scope.refreshProgress();
}, 500);
But the client get progress request will hold until to the end with 100%, without the progress that less than 100%. That is to say I get the progress response when the server slice application finished. I suppose laravel don't process the second request when it processing the slice.
Edited: I use below code to get the redis in the slice() after the redis->SET works well, this output the sliceProgress realtime.
Log::info($this->redis->GET('sliceProgress' . $uid));
Try to run this code in a background process like async queues or crons
while($s = fgets($pipes[2]))
{
if(strpos($s, "Progress:") !== FALSE)
{
Log::info(100 * substr($s, -10, 4) . '%');
$this->redis->SET('sliceProgress' . $uid, 100 * substr($s, -10, 4) . '%');
}
}
I believe the problem could be Session Lock. Consider you fired POST request following the Multiple GET calls. Now if session lock is there, none of the get request will be handled by PHP until the first one is done.
How Session Lock works?
Well php simply lock the session file to read, so all other apache processes have to wait. Laravel also use file based session management, so.
Now removing session lock is not a good idea, though you can do that. Try exposing this Get Service from different host or port.
I am not 100% sure how laravel handles session lock, so just cross check if this is the issue.
Removing Session Lock:
First Way: Use method once you done with session handling session_write_close.
Second : Pass read_and_close to be true while starting session with session_start
Not sure whether laravel allows to do that. There are other ways of doing realtime progress sync.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With