Concurrent AJAX requests within the Vaadin JavaScript extension

Currently, I am in the process of developing a straightforward Vaadin Extension using javascript where I subclass AbstractJavaScriptExtension. The main objective is to trigger a method call on the server side that will involve tasks such as loading data and updating the UI of the component. My aim is to have individual asynchronous requests for each component so that potentially lengthy database or webservice calls can run concurrently at the server side.

Given that continuous component updates are not required, employing Vaadin Push seems unnecessary. Instead, I prefer utilizing traditional XHR methods.

To achieve this, I have incorporated a javascript trigger function within my extension class as follows:

addFunction("trigger", jsonArray -> command.trigger());

(expressed in Java 8 syntax, where trigger() represents a method in a Functional Interface)

In testing, I initiated this trigger immediately in my javascript connector like so:

window.com_example_AsyncTrigger = function () {
    this.trigger();
}

I created a mock component that mimics slow loading by using Thread.sleep(), crafting three instances with varying delays (10 seconds, 6 seconds, and 2 seconds), while also logging the start and end timestamps of the loading process. Subsequently, I expanded three layouts with my extension to integrate each component when its respective trigger is activated.

Although all three triggers were successfully triggered, they operated within a unified request framework (indicated by the fact that they were executed on a single server thread). Consequently, after approximately 18 seconds, all three components were updated simultaneously, contrasting my expectation of a sequential display (2-second component first, followed by the 6-second component, and lastly the 10-second component) within roughly 10 seconds.

This led me to deduce that Vaadin condensed the function calls made during the creation of connection wrappers and issued the server side methods under a singular request. Thus, I decided to modify my javascript connector implementation to asynchronously invoke the client-side trigger() function:

window.com_example_AsyncTrigger = function () {
    var self = this;
    setTimeout(function() { self.trigger();}, 0);
}

Consequently, these triggers commenced firing in separate requests, evident from distinct worker thread names in the logs. However, they continued to execute sequentially as opposed to in parallel. Although the calls to self.trigger() occurred rapidly one after another, the actual XHR requests did not operate simultaneously. Each subsequent request only began once the prior one concluded.

Why is this occurring, and what steps can I take to overcome this limitation?

Answer №1

To ensure data integrity and prevent race conditions, the webserver does not process requests from the same client in parallel. When dealing with long running requests, it is important to perform asynchronous processing separate from the thread handling the initial request. Once the processing is complete, the results can be sent back to the UI using UI.access(...). The original thread will then resume and continue processing subsequent requests. However, there may be a delay in sending the result back to the server until the client initiates another request, as all long-running requests are handled concurrently.

Two options for managing this situation:

Option one is to regularly poll the server (utilizing a Vaadin addon) so that the result is included in the next poll response.

Alternatively, instead of polling, opt for push notifications. The performance impact should be minimal unless there are an excessive number of simultaneous users.

Further explanation:

In the Vaadin Framework, requests are processed sequentially following these steps:

  1. Handle changes sent by the client
  2. Trigger Listeners (such as ValueChange or Click)
  3. Send updates back to the client

If a second thread attempts to modify the URL while the first thread is in step three, it could lead to issues where only partial updates are transmitted. Vaadin raises an Exception in such cases, prompting the use of UI.access(...) to manage Runnable execution either immediately or after ongoing requests are completed. It's important to note that session-based locks apply across multiple UIs within the same session (e.g., different tabs of one application), ensuring sequential processing even among distinct user interfaces.

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

Guidance on calling a JavaScript function from a dynamically added control

The Master page includes a ScriptManager. Next, I have a Control with a ScriptManagerProxy and an UpdatePanel. Within the UpdatePanel, I dynamically insert another Control (which also has a ScriptManagerProxy) that needs to run some JavaScript code. In ...

Using jQuery and AJAX to submit a dynamic form

I am currently facing an issue with cloning a HTML drop down list using jQuery. The main problem I am encountering is that there seems to be no restriction on the number of cloned sections, and I need to store all these sections in a mySQL database. How c ...

Can you tell me if the "dom model" concept belongs to the realm of HTML or JavaScript?

Is the ability to use "document.X" in JavaScript to visit an HTML page and all its tags defined by the HTML protocol or the ECMAScript protocol? Or is it simply a choice made in the implementation of JavaScript, resulting in slight differences in every bro ...

What causes webpack to require 4 seconds for compiling a barebones react / redux project?

I am troubled by the fact that it is still compiling my node_modules even though I have specifically excluded it. How can I investigate and understand what exactly is happening? The output in the console seems like random characters. Is there a way to conf ...

Unable to retrieve file paths for assets using Node.js Server and Three.js

I am facing challenges when it comes to loading 3D models from a folder on my computer using a localhost node.js test server with the three.js library. Below is my app.js file that I execute via command line in the project directory using the 'node a ...

"Bootstrap-Wizard: How to troubleshoot the onPrevious function not working when used with an

I have been incorporating a bootstrap wizard into one of my applications, and I have encountered an issue. When attempting to utilize the index position of the tabs to achieve a specific goal, I found that it only works with the next button and not with th ...

What methods can I use to analyze the integrity of the data's structure?

Currently working on an API using NestJS and typeorm. I am in need of a way to verify the format of the data being returned to clients who make requests to it. For instance, when accessing the /players route, I expect the data to have a specific structure ...

Display text when hovered over or clicked to insert into an HTML table

I have an HTML table connected with a component field gameArray and I need it to: Show 'H' when the user's cursor hovers over TD (:hover) and the corresponding field in gameArray is an empty string, Fill the gameArray field after a click. ...

Removing outline from a Material UI button can be done using a breakpoint

Is there a way to remove the outlined variant for small, medium, and down breakpoints? I have attempted the following approach: const selectedVariant = theme.breakpoints.down('md') ? '' : 'outlined'; <Button name="buy ...

jQuery - contrasting effects of the before() and after() functions

I'm working with a sortable list that is not using jQuery UI sortable, but instead allows sorting by clicking on buttons. Sorting to the right using after() works perfectly, however, sorting to the left with before() is causing issues. First, here&ap ...

It is not possible to transfer information to a JSON document using node.js filesystem and browserify

In an attempt to convert incoming input data from a form into JSON format for storage without a backend, I am exploring the use of Node.JS module "fs" or "file-system". To make this work in a browser environment, I am using Browserify for bundling as it r ...

Tabulator - Enhancing Filter Results Using a Second Tabulator

I've implemented a Tabulator that displays search results, here is the code: var table = new Tabulator("#json-table", { layout:"fitDataFill", //initialFilter:[{field:"title", type:"!=", value:"ignoreList.title"}], ajaxURL:tabUrl, ajax ...

What is the best way to eliminate a CSS style from a div?

I have implemented jQuery Autosize to automatically adjust the height of textarea elements. It works perfectly when I focus on the textarea element. However, when I blur out of the textarea, I want to reset the height to its default value. I am unsure of ...

What is the proper way to utilize variables in package.json with npm version 7.x.x?

I am looking to utilize npm scripts to access keys found in the directories section. "directories": { "client": "client", "server": "server" }, "scripts": { "test:client&qu ...

The Angular JavaScript code displays the message variable in the web browser

When using Angular JavaScript, the browser displays {{message}}. I have tried multiple approaches but it still doesn't work as expected. var myApp=angular.module("mod",[]); myApp.controller("con", function($scope){ $scope.message = "hhhhhhhh"; }); ...

Having some trouble getting my AJAX request to work in Ruby on Rails due to cross-origin issues. I've

(apologies for my poor English) I am facing an issue while trying to make an AJAX request due to the same-origin policy. My application is still in development and I am using Ruby on Rails 3.2.3 with a Unicorn server. The AJAX request is located in an ass ...

Connect main data to sub-component

Example Vue Structure: <Root> <App> <component> Main function in main.js: function() { axios.get('/app-api/call').then(function (resp, error) { _this.response = resp.data; }) ...

In the ajax call, an empty JSON array object is sent as the data

Utilizing JSON data as a parameter for an ajax call: var startDate = dateFormatForSave($("#start_date").val().trim()); var arrayOfStudentsInfo = []; var table = $("#selected_students"); table.find('tr').each(function(i, el) { var rowId = $( ...

Ways to prevent scrolling on mobile web browsers?

I am currently facing an issue with disabling scrolling on a webpage when a user opens a popup, while still allowing them to scroll within the popup itself. The popup element is defined by the following attributes: #popup { display: none; width: ...

Is it possible to use Vuelidate for password validation in Vue.js?

I found a helpful reference on How to validate password with Vuelidate? validations: { user: { password: { required, containsUppercase: function(value) { return /[A-Z]/.test(value) }, containsLowercase: fu ...