Experimenting with parallelism using TypeScript/JS

Currently, I am tackling a TS project that involves testing concurrent code and its interactions with a database, specifically focusing on idepotency. My goal is to ensure that multiple requests modifying the same resource will either apply changes correctly or fail, without experiencing lost updates or double processing.

While I have extensive experience testing similar scenarios in Java due to its abundance of concurrency primitives like semaphores and barriers, I am struggling to translate this knowledge into TypeScript.

In Java, for instance, I would initiate 2 threads using a CyclicBarrier with 2 parties. These threads would reach the barrier, wait for each other, then continue execution, allowing me to validate the code's functionality effectively. If parallel execution could not be guaranteed, I would repeat the test multiple times or use more threads to increase chances of parallelism.

Unfortunately, I have not come across any similar concurrency primitives in JS to replicate this process. The closest workaround I found was busy waiting on a shared value or utilizing worker threads as suggested by some blogs.

If anyone has suggestions on how to approach this challenge in TypeScript, I would greatly appreciate it! This topic poses several difficulties, so links to relevant blogs, articles, and books are welcome!

Answer №1

It is crucial to note that unlike Java or other programming languages, JavaScript (in this case TypeScript) runs on a single thread. This means that only one line of TS/JS code can execute at a time. Although there are workarounds like WebWorkers, for the purpose of this discussion, let's assume they are not being utilized.

If your library will be used in an environment where multiple instances of your application are running concurrently, you will have truly parallel systems. For now, let's focus on the scenario where this is not the case.

Evaluating concurrency within a single node process

In this context, understanding how JS handles events via the event loop is key. Philip Roberts has an insightful talk on this topic from JSConf.

With a single node process and assuming the use of "async" functions, Promises are executed concurrently. However, the actual switching between asynchronous tasks occurs when performing operations like IO, web requests, etc.

A simple way to test your library under these conditions could be:

function test() {
    Promise.all([
        doSomething(),
        doSomething(),
    ]);
}

Evaluating concurrency in a multi-process environment

If your application is deployed across multiple machines simultaneously, testing becomes more complex. Directly simulating this scenario is challenging as initiating tests that call functions simultaneously requires starting multiple processes.

I would caution against attempting such tests, especially if the tasks you are evaluating are quick, as it may lead to unreliable results. Introducing an artificial delay by extending critical sections to take several seconds and calling both instances sequentially might provide better insights. Using Promise.all() here can help maximize concurrency effects. Ensure to account for potential misbehaviors during execution.

As for setting up and executing tests involving two processes, consider creating a web worker to establish a new V8 execution context in Node.js, or leverage a simple HTTP server for communication.

Considering alternative solutions

Given the inherent single-threaded nature of JavaScript, achieving true parallelism beyond Promise.all can be challenging. A possible workaround could involve writing a small script in another language to assess this behavior. While languages like Rust offer robust concurrency primitives, interoperability with JavaScript may present some challenges.

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

The code in check.js causes a square of dots to emerge on the screen in Skype

Trying to add a Skype call button to my page has been successful, but there's one issue - a pesky white dot keeps appearing at the bottom of the footer. The script source I used is as follows: <script src="http://download.skype.com/share/skypebu ...

What could be causing the issue with my css `content:` not functioning across different browsers, and how can I enhance cross-browser compatibility in all cases

Working on my first HTML/CSS project, I encountered a browser compatibility challenge. The code functions well in Firefox, IE, and Edge but fails in Chrome. Specifically, I am trying to make a button display alternating up and down arrows when clicked. Whi ...

How can I successfully transmit the entire event during the (change) event binding with ng-select in Angular 14?

I'm working on Front end Code <ng-select formControlName="constituencyId" placeholder="Select Constituency" (change)='onContituencyChanged($event)'> > &l ...

The calculator is malfunctioning and unable to perform calculations

export default function App() { const [activeKey, setActiveKey] = useState(0); const [storeArr, setStoreArr] = useState([]); function click(selector) { setActiveKey(selector); if (activeKey !== "=") { setStoreArr([...storeArr ...

Can the Disqus API be leveraged to retrieve comments from a particular website address?

It is my preference to accomplish this task solely with client-side JavaScript scripting, if feasible. ...

JavaScript: A pair of radio button selections

I'm facing an issue with a short form that has two questions and radio buttons for answers. When the first question is answered "No," I used JS code to disable options for the second question, which works fine. However, if the answer is changed back t ...

Error: The argument 'IParams' is not compatible with the parameter type 'IParams' in Typescript with NextJS14

I encountered an error in my code while using Prisma with Next.js 14 and TypeScript. The issue arises when trying to load product details via product ID. The error is captured in the screenshot below. Failed to compile. ./app/product/[productId]/page.tsx:1 ...

Having trouble with your Ajax post request?

I am currently working on creating a form that allows users to input information and submit it without the page refreshing. The processing of the form data will occur after the user clicks the submit button. To achieve this, I am utilizing jQuery and Ajax ...

Is it possible to display partial html templates by accessing the local url and blending them with the main index.html file?

Is there a way to view partial HTML templates locally without copying them into the main index.html file? I'm looking for a solution that allows me to access my partial templates through a local URL without having to manually paste them into the main ...

adjusting three sections within a flexible navigation bar

Having difficulties creating a dynamic navbar that changes on scroll and keeping the elements within the nav fixed when the menu options appear. For reference, you can check out this codepen: http://codepen.io/timothyfernandez/pen/azXQPV Any assistance w ...

Tips for sending information to an Express API through AJAX

While working on a website using Express and EJS, I encountered an issue with calling an API via AJAX. The problem arises when passing two values to the AJAX data upon button click, resulting in errors. Despite trying various solutions, I'm still stru ...

Ensure that the loader remains visible until all data has been successfully retrieved from the AngularJS service

Currently, I am facing an issue with the implementation of angularjs ui-router for state transitions along with a loader assigned to each view. The problem arises when moving from one state to another and the loader disappears before all the content from t ...

Tips on personalizing the formatting alert in Webclipse for Angular 2 using Typescript

Webclipse offers extensive formatting warnings for TypeScript code, such as detecting blank spaces and suggesting the use of single quotes over double quotes. However, some users find the recommendation to use single quotes annoying, as using double quotes ...

Top method in Angular 6 for verifying if a scrollable section has been scrolled to the very bottom

I am searching for a reliable solution in Angular 6 to determine whether a scrollable host component has reached its maximum scroll bottom. Despite my efforts, I have been unsuccessful in finding a functioning example of a function that can detect if a cu ...

Different categories of properties within a generic function

I'm attempting to modify certain fields of my object using field names. Here is the code snippet I have written: interface Foo { a: number[], b: string[], } type Bar = { [T in keyof Foo] : (arg : Foo[T]) => Foo[T] } function test<T ex ...

Exploring Date Comparisons in AngularJS

Currently, I am in the process of developing a web application using AngularJS and Rails. One of the features involves creating bookings through a bookings function. In the dashboard section of the app, I aim to have two tabs - one for Current Bookings and ...

Laravel triggers a 'required' error message when all fields have been filled

As I attempt to submit a form using an axios post request in laravel, I encounter an issue with the validation of the name and age fields, along with an image file upload. Here is a breakdown of the form structure: Below is the form setup: <form actio ...

Retrieve database SQL information using JavaScript to display data

I'm struggling to push the value from a textbox to SQL and display it. Despite reading numerous topics, I still can't figure it out. My explanation skills are lacking, but hopefully you can understand what I'm trying to achieve, especially i ...

Accelerated repository uses TypeScript to compile a node application with dependencies managed within a shared workspace

Struggling to set up an express api within a pnpm turborepo workspace. The api relies on @my/shared as a dependency, which is a local workspace package. I have been facing challenges in getting the build process right. It seems like I need to build the s ...

While the data from Angular $resource can be viewed, it is not accessible in the code

As a newcomer to Angular, I'm facing a frustrating issue that I need help with. My $resource is fetching data from the server in key/value pairs like detail.name and detail.email. While I can access this data using {{detail.name}} in the view, I&apo ...