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

CSS changes triggered by JQuery are ineffective

Having trouble modifying the CSS of a class in my HTML file. I've been struggling with this for quite some time and can't figure out what I'm doing wrong. (I've already attempted multiple versions, but nothing seems to work) Here' ...

Tips for achieving expansion of solely the clicked item and not the whole row

I am trying to create a card that contains a cocktail recipe. The card initially displays just the title, and when you click on a button, it should expand to show the full menu and description. The issue I'm facing is that when I click on one element, ...

Utilize JavaScript to send an email containing a link and content

In the html form, there are input fields for adding a new user to the database. Once a user is added, an email is sent to them using the sendmail() function in the adduser.js file. The email is sent successfully according to my standards. However, I want t ...

Implementing specifications throughout the entire nodejs route

In my Nodejs app, I have a RESTful API where I need to check for a user's role before sending a response with data or 404 error. apiRouter.route('/users') .get(function (req, res) { var currentUser = req.decoded; if(curr ...

Creating a JavaScript interface for an XML API generated by Rails?

Working with a large Ruby on Rails website has been made easier thanks to the REST support in Rails 2. The site's business logic can now be accessed through a consistent XML API. My goal now is to create one or more JavaScript frontends that can inter ...

What is the best way to implement nested iterations in Jade?

ul li a(href='') menu1 li a(href='') menu2 ul li a(href='') sub-menu2 li a(href='') menu3 ul li a(href=&apos ...

Is it true that node.js arrays can be considered as hashmaps?

Surprisingly, this code is functioning properly in node.js: var arr = new Array(); // also works: var arr = []; arr[0] = 123; arr['abc'] = 456; arr; // node.js: [ 123, abc: 456 ], chrome: [123] I've always believed that an array preserves ...

Javascript functions fail to execute as intended

I have a project called calc, which includes various functions such as init. Within this project, there are three buttons that I am adding to the div using jquery. When a user clicks on any of these buttons, it should trigger the inputs function. Based on ...

Guide to rearranging the sequence of items in a selected jQuery collection

I have created a JavaScript filter that targets elements with the class .single: There are numerous divs with the class .single, each containing multiple text elements. The filter has already been set up to hide all .single elements that do not contain an ...

Utilizing jQuery for JSON parsing

Within my JavaScript code, I am working with the following array: var versions = [{"id":"454","name":"jack"}, {"id":"4","name":"rose"} {"id":"6","name":"ikma"} {"id":"5","name":"naki"} {"id":"667","name":"dasi"} ] I need to extract the name from this ar ...

Experiencing difficulties when trying to upload images using multer in an Express application with Node.js

I have been using multer to successfully upload images into a folder within my project. Despite not encountering any errors while using multer, I am facing an issue where the upload is not functioning as expected in my project, although it works perfectly ...

Passing a deconstructed object as a parameter for a function

I'm having trouble understanding the parameter const Posts in the code snippet below. As a newcomer to node/React, I'm not sure if it's a destructured parameter object or just an object being passed as a parameter. The functions getPosts an ...

What causes jquery-ui resizable to set the width of the div with the "alsoResize" property?

I have created a series of divs structured like this: <div id="body_container"> <div id="top_body"> </div> <div id="bottom_body"> </div> </div> Additionally, I have implemented the following funct ...

The Gulpfile.js encountered an error while trying to load

My Visual Studio task runner is having trouble loading the gulp file. I am currently using VS2017 v15.9.4, but the project was developed some years ago. Failed to run "...\Gulpfile.js"... cmd.exe /c gulp --tasks-simple assert.js:350 throw err; ...

retrieve the value obtained from a promise in an outer scope

I need a simple function that returns the name. Here's my existing code snippet: getName(entity, id) { const promise = userServices.getName(entity, id).then((data) => { return data; }); / ...

Switch button displaying stored data in sessionStorage

I am facing an issue with my small toggle button in AngularJS. I have set up sessionStorage to store a value (true or false), and upon page load, I retrieve this value from sessionStorage to display the toggle button accordingly. Depending on the value sto ...

Using a text box in jQuery to perform basic calculations is a straightforward process

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Creating a Lens Calculator Web App</title> <link href="http://code.jquery.com/mobile/1.0a3/jque ...

What is the best way to make IE 10 display a pointer instead of an I-bar for a select list?

Is there a way to make IE 10 display a pointer instead of an I-bar when selecting from a list? Despite trying various methods found in similar questions, I have been unable to resolve this issue. The cursor: pointer property works as expected on other br ...

Difficulty encountered while using React.js map function to access specific JSON data

I'm encountering an issue where I am unable to read data from a JSON file. After checking that the data is stored in the component state and logging it to the console once the component is mounted, I attempted to render the URL string from the JSON da ...

Implement a logging system to track and record data from both incoming requests and outgoing responses on a server powered by Express and Node.js

Is there a way for my server to log the response and request data when posting to another server? Thank you. const request = require('request'); postToIotPlatform = function postToIotPlatform(req, res, next) { var formData = JSON.stringify( ...