localstorage and setInterval() with multiple tabs

Viewed 1648

We have some data stored in localstorage and we are using window.setInterval() to regularly update it every minute. In this interval we are continuously reading and writing the data.

Is it possible that concurrency issues can occur because we're using setInterval(), as multiple tabs can modify the data in localstorage simultaneously?


Edit 1: Explaining the scenario in detail:

Each tab is writing some data to localstorage against a key (say xyz) and also setInterval(), present in the running javascript, continuously checks the xyz key data. If some data exists against the key, then the setInterval callback sends it to the back end. Each tab running the same script will read the xyz key and append some data to the existing value after performing some logic.

I doubt that a concurrency issue may occur, like one tab may be reading the xyz key and adding data to the local storage and another tab might be doing the same thing at the same time. Now both will try to send the data at the same time, hence I may receive the same data 2 times in the back end.

3 Answers

Is it possible that concurrency issues can occur because we're using SetInterval() as multiple tabs can modify the data in local storage simultaneously?

There are two aspects to this:

  1. Are getItem/setItem (and their accessor equivalents) atomic?
  2. Can different tabs/windows doing a series of getItem/setItem calls have those calls interleaved?

On #1, surprisingly, the storage specification seems not to address this head-on. In a "Note" it says:

Note

This specification does not require that the above methods wait until the data has been physically written to disk. Only consistency in what different scripts accessing the same underlying list of key/value pairs see is required.

...which suggests to me that getItem/setItem will be atomic — that is, the datum you're getting/setting won't get corrupted if two threads call getItem/setItem at literally the same time.

Re #2, I don't think there are any guarantees, no. If each tab/window has its own thread, then in theory two of those threads could simultaneously enter the block of code doing these updates. Sometimes, tabs/windows share a single thread, in which case you'd be safe, but...

I would avoid having lots of different entries in localStorage that need to be updated in a coordinated way. Instead, I'd use a single entry with a structure. I usually use JSON for that. So getting the data looks like this:

let data = JSON.parse(localStorage.getItem("the-data")) || {/*...default structure here...*/};

and saving it looks like this:

localStorage.setItem("the-data", JSON.stringify(data));

so you could do

let data = JSON.parse(localStorage.getItem("the-data")) || {/*...default structure here...*/};
// ...modify the various parts of `data`...
localStorage.setItem("the-data", JSON.stringify(data));

then you're left with a simple race between the threads (the last one to write wins), but the stored data will be consistent.

In my opinion, it really depends on what you consider be "concurrency issues".

For the case of writing, I don't believe that you will have any issue, the browser will manage well what and when should write to localstorage. Your data will not be corrupted in the process.

For the case of reading, I believe that you will have problems when you are reading from the Tab1 but the last write was from the Tab2.

Related