Unusual occurrences when making several ajax requests to a single URL

I've encountered a peculiar scenario while working on a CherryPy server, and I'm seeking assistance in understanding the intricacies behind it. Here's the content of server.py:

import cherrypy
import os
import threading

class Root(object):
    def __init__(self):
        self.count = 0;
        self.lock = threading.Lock()

    @cherrypy.expose
    def app(self):
        with self.lock:
            self.count += 1
        return "Call #%d" % (self.count)

if __name__ == '__main__':
    cherrypy.quickstart(Root(), "/", {"/": { "tools.staticdir.on": True,
                                             "tools.staticdir.dir": os.getcwd() } })

This is a simple application containing some state managed by a mutex. Now, let's take a look at index.html:

<!doctype html>
<script src=http://code.jquery.com/jquery-1.8.2.js></script>
<script src=index.js></script>

(The minimal HTML structure aligns with ideas from this talk by Paul Irish). Moving on to index.js:

function request() {
    var cb = function (response) {
        console.log(response);
    };

    $.ajax({
        url: "/app",
        success: cb
    });
}

function go_slow(N, delay) {
    if (N > 0) {
        request();
        window.setTimeout(go_slow, delay, N - 1, delay);
    }
}

function go_fast(N) {
    var i;
    for (i = 0; i < N; i++) {
        request();
    }
}

window.onload = function () {
    //go_slow(100, 0);
    go_fast(100);
};

All these files should be placed within the same directory. When launching the CherryPy server and accessing http://localhost:8080/index.html, multiple instances of "Call #1" appear in the console, while the CherryPy log indicates only one GET request to "/app". Interestingly, Firefox reveals expected behavior compared to Chrome.

If the go_fast() method is swapped with go_slow(), which uses 'trampolining' logic to manipulate ajax requests individually over time, the "#1" through "#100" output can be observed on both browsers.

By altering the app() method in the server to accept but ignore an argument:

@cherrypy.expose
def app(self, i):
    with self.lock:
        self.count += 1
    return "Call #%d" % (self.count)

and reflecting this change in request() and go_fast():

function request(i) {
    var cb = function (response) {
        console.log(response);
    };

    $.ajax({
        url: "/app/" + i,
        success: cb
    });
}

function go_fast(N) {
    var i;
    for (i = 0; i < N; i++) {
        request(i);
    }
}

The display reverts back to showing "#1" through "#100" consistently. The caching phenomenon in Chrome puzzles me as only one ajax call reflects in response, thereby repeating "Call #1" multiple times. Firefox behaves differently, emphasizing that "caching" might not be solely responsible.

In varying scenarios, the caching mechanism seems evaded. Trampolining may reset the context of each ajax request, negating potential cache retention. On the other hand, appending a positional argument ensures unique URLs per call, effectively bypassing any caching protocols.

Can someone elucidate what precisely unfolds here? Is this an idiosyncrasy with how Chrome handles rapid fire ajax requests or does it unveil profound issues pertaining to stateful ajax resources?

Answer №1

In my opinion, the issue at hand seems to be stemming from a race condition paired with the utilization of the cache: false setting on the client-side. It is crucial to keep in mind that your object Root is being shared within a thread pool.

At timestamp A, you make alterations to self.count. Simultaneously at timestamp A, other X requests (threads) are fetching the newly updated parameter which was tweaked at timestamp A - 1 within the with block and fail to retrieve the new count during this specific request.

The discrepancy in the return values is determined by the processing throughput of cherrypy's thread pool as one request modifies the data while another is already locking it for retrieval outside the with statement.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing JQuery to Access the Return Value from an Ajax Request Beyond the Scope of the Call

Hey there! I am currently facing an issue with an ajax call. The return value (data) from the call is stored in a variable called mydata, but unfortunately, I need to access this variable outside of the ajax call. Due to certain constraints, I cannot inc ...

After the entire webpage has loaded, the jQuery AJAX method encounters a failure when attempting to update the

I am relatively new to using jQuery AJAX, so please be patient as I try to explain my situation. I am working on implementing a like button for my website that functions similarly to the Facebook like button. To enable users to click on the like button, th ...

Serve as a proxy for several hosts with identical URL structures

I've been utilizing the http-proxy-middleware to handle my API calls. Is there a way to proxy multiple target hosts? I've searched for solutions in the issues but still haven't found a clear answer. https://github.com/chimurai/http-proxy-m ...

How can we add a class to a radio button using jQuery when it is checked, and remove the class when it

I'm looking for help with using jQuery to toggle between two radio buttons and display different divs based on the selection. jQuery(document).ready(function($) { if ($('#user_personal').is(':checked')) { $('.user_co ...

I am experiencing issues with staying logged in while using Passport and sessions. The function "isAuthenticated()" from Passport continuously returns false, causing me to not remain logged in

I have been working on implementing authentication with Angular, Passport, and sessions. I can successfully create a new user and log in, but I am facing an issue: Problem Every time I check if the user is authenticated using Passport's isAuthentica ...

HighCharts velocity gauge inquiry

I recently integrated a highcharts speedometer with PHP and MYSQL on my website. Everything seemed to be working smoothly until I added the JavaScript code for the speedometer, causing it not to display. There are no error messages, just a blank screen whe ...

Utilize $.get AJAX to extract data from a multidimensional JSON array

Struggling to make two functions work on my form that uses AJAX and jQuery to look up an array. One function is functional while the other seems to be causing confusion with over-analysis and extensive troubleshooting. Any insights into what may be missing ...

"Implementing ASP.NET MVC4 with Razor: Dynamically filtering a dropdown list based on the selected value from another dropdown

Currently, I am facing a challenge where I need to filter the options of a dropdown list based on the value selected from another dropdown. Within my database, there are tables containing all countries and all cities in the world, with a foreign key linkin ...

Displaying markers and coordinates in the center circle of a Google Map using Vue.js

Is there a way to display the markers that fall within the specified radius on my map? I need to showcase these locations based on their proximity to a central point, as this will be essential for developing a function that identifies places within a certa ...

"Ensuring Username Uniqueness in AngularJS and CakePHP3: A Step-by-Step

<input type="email" id="username" dbrans-validate-async="{unique: isUsernameUnique}" ng-model="username" required class="form-control" name="username"> $scope.isUsernameUnique = function(username) { $http.get(url+'/isUsernameUnique&apo ...

Is there a way to manually add route resolve data to a controller without using automatic injection?

Two routes in my application share a controller, but one route requires data to be resolved before the view loads while the other does not. Here is an example of the routing segments: ... when('/users', { controller: 'UsersCtrl', ...

Using jQuery's setInterval to consistently refresh the value of a data attribute

I am struggling to dynamically update the data-left value of a div with the class name "tw_marquee_scroller" every 1 second. The intended behavior is for the value to increment by 10 each time, starting at 10 and increasing by 10 in subsequent seconds. H ...

Creating Projects Without a Build System in Sublime Text 3

I'm having trouble getting the sublime build system to function properly. When attempting to run my code, I receive a "No Build System" error message. I have already set the build system to Automatic under Tools->Build Systems and saved the file as N ...

Vercel deployment issue: Hidden input values not being detected as expected

Whenever I attempt to update the data on Vercel, an error message is displayed: invalid input syntax for type uuid: "undefined" - unable to save Oddly enough, the data updates successfully when done locally. This is how I submit the form: <form onSu ...

Unable to receive response from Ajax request

Currently, I am making use of Ajax to send a request to a php file from a form. My intention is to retrieve a result from this php file. Below is the code snippet: <script type="text/javascript"> jQuery(document).ready(function($){ $(&a ...

What is the best way to pre-fetch data using axios in Vue?

My app requires offline functionality for drivers operating in remote areas with limited internet access. To address this, I aim to pre-download all necessary data using Axios requests when an internet connection is available. This way, the app can retriev ...

Is there a way to change the color of just the most recently clicked anchor element <a>?

I have a sidebar with anchor elements (Link 1,2,3 in my HTML). I want the text color of these anchors to change when clicked. Additionally, I need only one anchor element to be colored at a time, meaning the previous one should return to its normal color. ...

Navigating through different sections of your Angular app can be easily accomplished using

My current project structure is set up like this: The application I am working on is hosted in a subdirectory called /my-scripts/vk.plants. This means that when I request this URL, it loads layout.html and returns it to the user. layout.html contains the ...

excess white space appears in the mobile version

I recently completed a website using both materializecss and bootstrap platforms. While I know this may not be the best practice, it worked for my needs. However, I am facing an issue with the mobile view. When I reduce the viewport size, a margin appear ...

Discover the best method for transferring MySQL data between pages

Can anyone help guide me in the right direction on how to allow a user to click a link within a PHP While Loop generated MySQL table and pass that data to another page? I've searched through similar questions but haven't found a solution that fit ...