Saturday, August 18, 2018

Tab-to-tab communication using BreezeJS and localStorage

I'm using BreezeJS and storing/restoring data in local storage. That's working great. The problem occurs when the user opens multiple tabs. Changes in each tab clobber each other. Changes should be synchronised between tabs.

NB: BreezeJS will take care of merging changes, I just need to deal with race conditions between tabs.

var stashName = 'stash_everything';

window.setInterval(function () {
    var exportData = manager.exportEntities();
    window.localStorage.setItem(stashName, exportData);
}, 5000);

addEvent(window, 'storage', function (event) {
  if (event.key == stashName) {
    var importData = window.localStorage.getItem(stashName);
    manager.importEntities(importData);
  }
});

I've tried listening to the 'storage' event, but I haven't been able to get it working successfully. I either still clobber changes, or get into an infinite loop.

The crux of the issue is that I'm just saving on a timer; if I only saved after user interaction, then I'd avoid (most) race conditions. There's no 'has the user changed anything since last time I asked you' call in breeze, though, as far as I can tell.

Does anyone have advice on how to approach this?

Solved

Hmm this doesn't seem like it is impervious to having problems for many reasons but the main one would be that you still won't prevent concurrent saves from each tab with different data sets. That being said, if you are comfortable with the fact the two caches could be out of sync just use some unique identifier -

Somewhere in your app on load -

var stashName = 'stash-everything-' + new Date().getTime();

window.setInterval(function () {
    var exportData = manager.exportEntities();
    window.localStorage.setItem(stashName, exportData);
}, 5000);

Now each tab would have a unique set of data to work with.


No comments:

Post a Comment