0

I have added a script to an admin page on a magento site to initiate a long running process and periodically query the progress using AJAX (or XHR) requests so that it can update a progress bar.

The first request is to the controller function that starts a long running process:

var startfeed = new XMLHttpRequest();
startfeed.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        feedComplete(this);
    }
};
startfeed.open("GET", thisFeedUrl, true);
startfeed.send();

In the code above, the thisFeedUrl variable is the appropriate URL for the following controller action:

public function thistakesalongtimeAction()
{
    very_slow_function();
}

The very_slow_function writes it's current progress to a file, which can be accessed by the following controller action:

public function getprogressAction(){
    $progressFileName = getProgressFileName();
    echo file_get_contents($progressFileName);
}

This controller is accessed by the following javascript:

var feedProgress = new XMLHttpRequest();
feedProgress.onreadystatechange = function () {
    if (this.readyState == 4 && this.status == 200) {
        progress = JSON.parse(this.responseText);
        // Update progress bar
        setProgress(progress);
    }
};
feedProgress.open("GET", thisFeedUrl, true);
feedProgress.send();

The problem is that the requests for progress do not complete until the long running action has completed. How can I get the progress bar to update correctly while the long running process is incomplete.

1 Answer 1

0

The AJAX requests for the progress reports are probably being forced to wait for the first request because they are running in the same PHP session. The request that takes a long time to complete acquires the session lock and holds it until thistakesalongtimeAction() has returned. That means that the other action will wait for the lock to be released.

You can force the lock to release early by closing the session with session_write_close():

public function thistakesalongtimeAction()
{
    session_write_close();
    very_slow_function();
}

You should also be careful that you don't start too many long running requests. If you have lots of slow actions that you run concurrently, you might hit the browser's limit for the number of concurrent requests and then you won't be able to make the progress-report requests.

1
  • Note: Don't forget that this will only work if very_slow_function() doesn't need the session to remain open. If it does need to read or modify the session, this will not work.
    – Lex
    Commented Jan 12, 2017 at 14:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.