Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the right way of making continuous ajax calls?

I have some code like this to update a graph on my page in real-time every 30 seconds:

var counter = 30;

$(function() {
    prepare();
    update();
});

function update() {
    $("#timer").html("Refreshing in " + counter + " seconds...");
    counter--;

    if (counter == 0) {
        counter = 30;
        prepare();
    }

    setTimeout(update, 1000);
}

function prepare() {
    $.ajax({
        type: "POST",
        url: "Service.asmx/GetPlotData",
        contentType: "application/json; charset=utf-8",
        success: OnSuccess, // this function plots the new data
        error: OnError
    });
}

This seems to be working fine except after 16-20 hours of continuously making ajax calls, I get an error back from the server:

Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.

I fired up the debug console and this is what I observe:

AJAX calls are getting fired correctly

enter image description here

Before the 16-20 hour period, there are some instances where the latency increase (this is where the Timeout error is seen for the first time)

enter image description here

Finally, the code manages to hit some bottleneck. Latency increases for every single call and the front-end breaks. No call after the blue arrow below returns any data. Instead, it throws the timeout error.

enter image description here

I am sure I am doing something fundamentally wrong. Any ideas on how to address this problem?

EDIT: Server-side code

My connection string:

Data Source={0};Initial Catalog={1};Integrated Security=True;MultipleActiveResultSets=true

The code to pull the records:

try
{
    string ConString = Constants.connString;
    con = new SqlConnection(ConString);

    cmd = new SqlCommand(sql, con);
    con.Open();
    dr = cmd.ExecuteReader();

    while (dr.Read())
    {
        // Add the records into an object
    }

}
catch (Exception x)
{
     // Send back some error text.
     // This is what is giving out the Timeout error
}
finally
{
    con.Close();
}

Unless I am missing something, I am closing the connection after getting the records using the con.Close() or is there anything else I need to do?

EDIT 2: Changing the above code as follows. Is this correct?

try
{
    string ConString = Constants.connString;

    using (con = new SqlConnection(ConString))
    {
        cmd = new SqlCommand(sql, con);
        con.Open();
        dr = cmd.ExecuteReader();

        while (dr.Read())
        {
            // Add rows to object
        }
    }

}
catch (Exception x)
{
    // Handle error
}
finally
{
    con.Close();
}
like image 820
Legend Avatar asked Oct 08 '12 16:10

Legend


People also ask

How do you call AJAX every 5 seconds?

The jQuery code to call AJAX in every 5 secondsready(function(){ sendRequest(); function sendRequest(){ $. ajax({ url: "example. php", success: function(data){ $('#listposts').

Is there a way to limit the time an AJAX call will run?

Not possible. It's the browser's responsibility.


2 Answers

It looks like a server-side issue with too many connections to a database. How're you connecting to the DB? Are you closing the connection after using it? Try closing the connection after a number of connections.

like image 119
Juan Pablo Santos Avatar answered Oct 19 '22 05:10

Juan Pablo Santos


"I get an error back from the server" makes me think this is a server side resource leak. What happens if you run two browser tabs in parallel, or two browsers in parallel, or two hosts with their own browsers hitting the server in parallel?

Does your browser memused rise over time?

If you have access to server side logs, that would also be a point to dive in.

EDIT

After seeing server code, you may want to close the reader as well for safety; I would be surprised if this caused a leak, but you never know. I'm more familiar with Java, where this can cause a leak depending on the underlying driver being used.

dr.Close();
con.Close();
like image 38
Cory Kendall Avatar answered Oct 19 '22 05:10

Cory Kendall