I have a webpage that uses HTML LocalStorage. It is common to have multiple tabs/windows of this page open at the same time. Since these all use the same LocalStorage and LocalStorage does not provide transactions or similar, I would like to implement some form of mutual exclusion to prevent the different tabs/windows to overwrite each other's data in an uncontrolled manner.
I tried to just port my test of the Burns/Lynch mutual exclusion algorithm to the browser by simply storing the boolean[] F
in LocalStorage.
Things work perfectly in FireFox, but Chrome allows an average of about 1.3 processes (mostly just one, sometimes two and very rarely even 3 or more) into the critical section at the same time, and Internet explorer allows an average of 2 processes (mostly 1, 2, or 3, sometimes even more) in.
Since the algorithm has been proven correct and my implementation is super-trivial and I've tested the heck out of it otherwise, the only reason that I can come up with for why this is happening is that in Chrome and IE there is a delay between when I write to LocalStorage in one tab/window and when the new value will be visible in all other tabs/windows.
Is this possible? If so, is there any documentation or are there any guarantees on these delays? Or, better yet, is there some kind of "commit"- or "flush()"-call that I can use to force the changes to propagate immediately?
UPDATE:
I put together a little jsfiddle to test out the round-trip times:
// Get ID
var myID;
id = window.localStorage.getItem("id");
if (id==1) { myID = 1; window.localStorage.setItem("id", 0); }
else { myID = 0; window.localStorage.setItem("id", 1); }
// Initialize statistics variables
var lastrun = (new Date()).getTime();
var totaldelay = 0;
var count = 0;
var checks = 0;
document.documentElement.innerHTML = "ID: "+myID;
// Method that checks the round-trip time
function check() {
window.setTimeout(check, 1); // Keep running
value = window.localStorage.getItem("state");
checks++;
if (value==myID) return;
window.localStorage.setItem("state", myID);
now = new Date().getTime();
totaldelay += now - lastrun;
count++;
lastrun = now;
document.documentElement.innerHTML = "ID: "+myID+"<br/>"+
"Number of checks: "+checks+"<br/>"+
"Number of round-trips: "+count+"<br/>"+
"Checks per round-trip: "+checks/count+"<br/>"+
"Average round-trip time:"+totaldelay/count;
}
// Go!
window.setTimeout(check, 1000);
If I run this fiddle in two different windows, I get the following numbers in the second window I opened:
Browser | Checks per round-trip | Average round-trip time
------------------+-----------------------+-------------------------
Firefox 24.3.0 | 1.00 | 6.1 ms
Chrome 46.0.2490 | 1.06 | 5.5 ms
IE 10 | 17.10 | 60.2 ms