My application runs up to 180 AJAX jobs that are IO-intensive at the server side (long running SELECT
queries).
I would like to optimize the load of the multiple CPU cores I have available, switching from a design in which each AJAX call is executed sequentially to a design in which these requests are executed with a maximum of, say, 4 in parallel.
A possible, but ugly solution could be issuing all 180 requests at the same time on the client and have the server use a Semaphore
stored at Session
or Application
level. I will discuss about application workloads later.
I would like to find a nicer solution in which calls are all started in order (each row on a table is a different check query) but when any terminates, the next is started and there are a number (namely 4) of concurrent AJAX requests with their respective loader indicators.
I have tried to use Threadpool-js but I have found myself that i cannot use jQuery from workers
My current code is the following
function GlobalCheck() { //entry point
if (ValidateDate()) {
//Below are global variables
list = $(".chkClass:checked"); //Only checked rows deal to AJAX request
num = $(".chkClass:checked").length; //Total number of ajax calls
done = 0; //Count of complete calls. When it reaches num we are done!
if (list.length == 0) {
alert('...');
return;
}
$(".pMessage").fadeOut();
$(".tbStatus").html('');
$(".submit").hide();
$(".exportFunctions").fadeOut();
$(".loader").show();
$(":checkbox").attr('disabled', true);
SingleCheck(0); //simplification, I do other non interesting things here
}
}
function SingleCheck(index) {
aValue = $($(list).get(index)).val();
var splitted = aValue.split('_');
$('#loader_' + aValue).show();
$('#green_' + aValue).hide();
$('#yellow_' + aValue).hide();
$('#red_' + aValue).hide();
$('#print_' + aValue).hide();
$('#xls_' + aValue).hide();
$('#summ_' + aValue).hide();
$.ajax({
type: 'GET',
url: '@Url.Action("Single", "Check")',
data: {
pType: splitted[0],
pIdQuery: splitted[1],
pDateBegin: $('#date_begin').attr('value'),
pDateEnd: $('#date_end').attr('value'),
pNow: Math.floor(Math.random() * 1000000)
},
success: function (data) {
if (!CheckSessionExpired(data)) {
//alert(data);
$("#tdStatus_" + aValue).html(data);
$("#loader_" + aValue).hide();
done++; //Done 1 more query
$(".progress").each(function (i, cRow) { $(this).html([update status]); });
if (done == num) { // Finish?
FinishCheck();
}
else {
SingleCheck(done); //Go to the next
}
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
RedirectToError();
}
});
}
Result is the following:
Question is: what approach can I follow in order to create concurrent AJAX requests in my scenario?
[edit] forgot to discuss application demands: this application is running live but is not serving a large user base. When a user submits data to be checked, the application will perform intensive operation, while staying idle for long periods of time.