1

I'm trying to make a progress bar that fill in real time. I've tried to adapt this example to my laravel project but probably I missed something.

My html code and javascript code:

<div  style="border:1px solid black;width:500px;height:80px">
    <div class="bar" style="background-color:green;height:inherit;width:0px"></div>
</div>
<p id="progress"></p>
<button onclick="longJob()" type="button">long job</button>
<button onclick="getProgress()" type="button">progreso</button>

<script type="text/javascript">
function longJob(){
    $.ajax({
        url: "/longJob",
        type: "POST",
        success: function (response) {
            $('.bar').css('width', '250px');
        }
    })
}
function getProgress(){
    $.ajax({
        url: "/getProgress",
        type: "POST",
        success: function (response) {
            var progress = response['progress'];
            $('#progress').text(progress);
            if(progress < 10){
                getProgress();
            }
        }
    })
}
getProgress();
</script>

And my php functions:

public function longJob(){
    for($i=1;$i<=10;$i++){
        Session::set('progress', $i);
        sleep(1);
    }
    return response()->json([
        'success' => 'true'
    ]);
}
public function getProgress(){
    $progress = Session::get('progress');
    return response()->json([
        'progress' => $progress
    ]);
}

When I load my page the function getProgress() starts to run over and over, retrieving '0'. When I click on the button for long job getProgress() stops for 10 seconds until longJob finishes and then retrieves progress of 10.

Juan Lopez
  • 361
  • 1
  • 3
  • 16
  • Are you using Apache or the build in PHP server? – Vivek May 14 '19 at 09:56
  • @Vivek I'm using XAMPP – Juan Lopez May 14 '19 at 09:56
  • Are you using sessions? Then it is probably a problem with locking. Try and use `session_write_close` as soon as possible in your long-running script. (If your long-running script needs write access to the session til the very end though, there is not much you can do about that.) – 04FS May 14 '19 at 10:08
  • @04FS Yes I'm using sessions. I've tried to use `session_write_close` after `Session::set('progress', $i);` but it doesn't work – Juan Lopez May 14 '19 at 10:15
  • Yeah in Laravel that would have to be something like `$request->session()->save();`, https://stackoverflow.com/questions/41544698/how-to-session-write-close-in-laravel But it says there Laravel wasn’t implementing any session locking in the first place, so I am not sure that’s the actual issue here. (But I can’t tell whether that statement is correct either, I’d expect at least for a file-based session storage handler, there must be some sort of locking implemented.) – 04FS May 14 '19 at 10:36

1 Answers1

1

The issue here is not related to JavaScript or your Ajax implementation. Both the Ajax functions you defined here should work asynchronously.

This issue is related to the PHP server being blocked by the /longJob request. Until the /longJob request is completed, no other requests are being handled by your server.

This causes your getProgress function to wait for the response which comes only after the /longJob request is fulfilled.

The PHP built-in server does not run each request in a separate instance. So one long-running request will block all other requests. You will have to use the XAMPP server.

Vivek
  • 2,665
  • 1
  • 18
  • 20
  • And how can I get the expected result then? – Juan Lopez May 14 '19 at 10:09
  • How are you currently running the Laravel installation? Do you copy the files to the htdocs folder or use ```php artisan serve``` command? – Vivek May 14 '19 at 10:13
  • 1
    ```php artisan serve``` command does not use XAMPP like you mentioned in the comments to the question. It uses the PHP buit in server which does not run each request in separate instance. – Vivek May 14 '19 at 10:18
  • oh! Sorry then. Is there a way to change that behaviour? – Juan Lopez May 14 '19 at 10:19
  • I have updated the answer. You can find details of installing Laravel inside XAMPP here. https://stackoverflow.com/questions/23881891/laravel-4-1-installation-with-composer-in-xampp – Vivek May 14 '19 at 10:22
  • Ok now I've no problems with request so I will give you the accepted answer but I still need help with something: the session variable is always 0 until the long job has finished. – Juan Lopez May 14 '19 at 10:53
  • Try using ```$request->session()->put('progress', $i);``` and ```$request->session()->get('progress');```. Incase that doesn't solve, create a separate question. – Vivek May 14 '19 at 11:19
  • I've found the solution: Adding `Session::save()` after `Session::set('progress', $i);` – Juan Lopez May 14 '19 at 11:41