5

I have an extension that reads a feed of timestamped messages and alerts users to them.

I track the highest timestamp since user opened a message, anything below that being "read". It works well, but problems start when a user has several Chrome installs: he's presented with items he already read on another machine.

Enter chrome.storage.sync API. I can set the highest timestamp to sync between instances, but that presents me with a race condition.

If I use chrome.storage.sync.get immediately after the browser is launched or wakes from sleep, it will get stale local data and will not wait for a sync to happen - tested to be true. So the user is still alerted, even if for a brief period before the alert is cleared - which is confusing.

I can detect extension launch, I can (sort of) detect wake from sleep. Maybe even offline/online events. But what do I do next to give Chrome a chance to sync data? A naive solution would be this:

var syncSleepTimeout = null;

function getUpAndRunning(){
  clearTimeout(syncSleepTimeout);
  syncSleepTimeout = null;
  doActualWork();
}

// Called upon wakeup/start/online event
function justWokeUp(){
  // Give sync a chance to happen
  syncSleepTimeout = setTimeout(getUpAndRunning, 3000);
}

chrome.storage.onChanged.addListener(function(changes, area){
  if(area === "sync" && syncSleepTimeout) getUpAndRunning();
});

To the best of my knowledge, chrome.storage.sync does not provide any state information or events, not even whether cloud sync is actually enabled by the user. I filed a couple of feature requests to that effect, but they are completely ignored.

  1. Is there a more elegant solution to this?
  2. What would be a robust solution of detecting wakeup / getting online events?
Xan
  • 74,770
  • 16
  • 179
  • 206
  • I think that the best solution at the moment is to store the timestamp on a remote server and store a user ID in the sync storage area. (PS. I've triaged your bug reports, feel free to mail me next time if you feel that your ticket has not received the attention it deserves.) – Rob W Jun 03 '14 at 12:07
  • @RobW Thank you very much; I've even posted the requests on chromium-extensions list [as suggested by documentation](https://developer.chrome.com/extensions/faq#faq-fea-02), but it also got no attention there. – Xan Jun 03 '14 at 12:11
  • I answered the sleep detection part yesterday on this other question: http://stackoverflow.com/questions/23933868/chrome-extension-check-if-background-script-is-running/23995990?noredirect=1#comment37001930_23995990 – Zig Mandel Jun 03 '14 at 13:12
  • @ZigMandel I indeed had in mind this solution. It doesn't catch connectivity problems though, I'm going to experiment with `document.ononline` events – Xan Jun 03 '14 at 13:14
  • Chrome has a notification when going online/offline i use it on my extension as well – Zig Mandel Jun 03 '14 at 17:14
  • Incorrect -1 on my question. – Cris Oct 23 '14 at 08:09

1 Answers1

9

Author of the Storage API here. I don't have enough reputation to reply to the comment thread apparently. Anyway, sync doing its thing and the network status/events are certainly not going to be tightly coupled. Sync will "finish" even if the computer is offline, but if the computer is online then sync will likely not be "finished" immediately.

An event like chrome.storage.onStabilized, in some form, is a moderately frequent request. There are complications beyond the Storage API, though. It would be a misleading API to claim that sync has been loaded as some way of inferring a barrier between computers. The sync servers aren't necessarily wired up that way.

E.g. even if the user has read something on computer A, you update storage, user opens computer B, sync says it's loaded... that doesn't necessarily guarantee that the change from computer A has been fully committed and pushed out to clients.

As a result what we usually advise is to be tolerant of that uncertainty. Like you've done, give a bit of grace before aggressively inferring state of the system. Maybe do use navigator.onLine as a rough metric.

kalman
  • 654
  • 5
  • 3
  • 1
    1) Now you have enough rep; 2) Would it be possible to expose a timestamp of last sync to server? That would solve my problem – Xan Jun 03 '14 at 18:36