Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot realtime read from redis

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

like image 954
LF00 Avatar asked Dec 21 '16 03:12

LF00


2 Answers

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) . '%');

}
}
like image 93
Bara' ayyash Avatar answered Oct 08 '22 11:10

Bara' ayyash


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.

like image 2
anwerj Avatar answered Oct 08 '22 13:10

anwerj