I have several time consuming database queries to run. Each has been built to be triggered from an option chosen on a web page. I thought I was being quite cunning by firing off the work via several AJAX requests.
I presumed that multiple requests would be split over multiple processes/threads meaning the work would be completed relatively quickly for the user.
However, the requests seem to be processed in serial, meaning that no speed benefit is felt by the user.
Worse still, AJAX requests to update the page also wait in line, meaning they fail to respond until the previous requests have all completed.
I have read that this may be caused by the PHP sessions being locked.
What is the usual approach for this kind of issue?
- Is there a way to force AJAX requests to work asynchronously?
- Can I stop PHP from locking the sessions?
- Should I use a seperate process via cron to fire background workings?
Thanks!
NB This project has been built using the symfony framework.
AJAX uses jQuery
// Get the content
$.get('/ajax/itemInformation/slug/'+slug, function(data) {
$('#modal-more-information').html(data);
});
If you are using sessions at all during any of the given AJAX requests, they will effectively execute serially, in order of request. This is due to locking of the session data file at the operating system level. The key to getting those requests to be asynchronous is to close (or never start) the session as quickly as possible.
You can use
session_write_close(docs) to close the session as soon as possible. I like to use a couple of helper functions for this, theset_session_varfunction below will open the session, write the var, then close the session – in and out as quickly as possible. When the page loads, you can callsession_startto get the$_SESSIONvariable populated, then immediately callsession_write_close. From then on out, only use the set function below to write.The get function is completely optional, since you could simply refer to the
$_SESSIONglobal, but I like to use this because it provides for a default value and I can have one less ternary in the main body of the code.Be aware that there are a whole new set of considerations once the AJAX requests are truly asynchronous. Now you have to watch out for race conditions (you have to be wary of one request setting a variable that can impact another request) – for you see, with the sessions closed, one request’s changes to
$_SESSIONwill not be visible to another request until it rebuilds the values. You can help avoid this by “rebuilding” the$_SESSIONvariable immediately before a critical use:… but this is still susceptible to a race condition.