[Leader Election] IndexedDB method doesn't work in Safari #414
Comments
|
Can you check if you have any errors on the console. This is very likely and indexeddb+safari bug, can you try different safari versions and maybe pin down which one is affected. |
|
Unfortunately I haven't seen any errors in the console, and the version of Safari I'm currently using is Safari 14.0.1 (14610.2.11.51.10). I have also added it to the issue description |
|
Can you reproduce also on the "official" example page https://pubkey.github.io/broadcast-channel/ ? |
|
Hmm. |
|
In my opinion it has something to do with the throttling of DOM Timers in pages that transitioned into a so-called background mode. It's a well-known fact that DOM timers are throttled in background tabs, but it turns out that in Safari(WebKit) the timers are throttled in a very aggressive way, once the timer nesting level reaches the maximum value which is set to I have prepared a simple/test page that demonstrates this effect and while playing around with it in Safari, I saw a delay of ~60 seconds instead of planned 100 ms. Honestly, I was about to fill in a separate ticket regarding the potential problems that might occur because of throttled timers as just last night I intentionally left several tabs in the background in Chrome and even though there was only a single elected leader when I was closing my laptop, by the moment I re-opened my laptop today in the morning all tabs became a leader. It wasn't the I believe it's a pretty important issue given that:
Please let me know if you think it's better to create a separate issue where we can discuss the potential issue of throttled DOM Timers. |
|
This is a relevant discussion on what a nesting level of DOM Timers is and how to interpret it especially in the context of |
|
Thank you for the good investigation. As a last approach we can of course set the localstorage method as default and make the webworker support optional. But this would cause a breaking change and still make the leader election buggy when people want webworker support. |
Not sure I understand the question, but I guess the nesting level is simply a "counter" of a recursive function invocation scheduled via a function setTitle(title) {
window.document.title = title;
}
function now() {
return Date.now();
}
function updateTitle(interval) {
let count = 0;
let lastUpdatedAt = now();
setTimeout(
function task() {
setTitle(`${++count} - ${now() - lastUpdatedAt} ms`);
lastUpdatedAt = now();
setTimeout(task, interval);
},
interval
);
}
updateTitle(100);
It might be an option but at the same time might be problematic as well due to an autocommit feature of IndexedDB transaction. There was a proposal to add an explicit
Could it be solved by clamping a given value of |
The only case when multiple tabs became leader in Chromium was when tabs were left in the background over the night. |
|
It looks like the "native" method is also suffering from the same problem, i.e. This morning I found out that all "native" tabs became a leader over the night, while the tabs running a "localStorage" method were still in the correct/expected state. (see the screenshots below) Having looked briefly through the source code of Chromium, I've got an impression that
In other words, it means that if a The reason why a "localstorage" method is still working correctly is perhaps because a I think the next logical step would be to reach out to Chromium engineers to clarify the details of heuristics they apply when a browser page transition into a "hidden" state as this part seems like a black box to me at least. |
|
Ok that was a lot of new information for me. |

Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.





OS: macOS 10.14.6
Browser: Safari 14.0.1 (14610.2.11.51.10)
While playing around with the library, and with its implementation of a leader election algorithm in particular, we ended up in a situation when in Safari multiple browsing contexts (tabs) are elected as a leader unless a
localstoragemethod is forced.In order to illustrate the drastic difference in how a leader election works in Safari with different method and the same
responseTime, please take a look at the following videos, whereresponseTimevalue is set)responseTime = 50,method = idb)responseTime = 50,method = localStorage)On each of these videos you can see how we open a simple HTML page containing the following code snippet (in some cases it was slightly adjusted in order to specify a custom responseTime or force the usage of a specific method of cross-tab communication:
CPU usage was pretty low and no "heavy processes" were running in the background while we were capturing the videos, so it's not very likely that the behaviour we observed was caused by the throttling of DOM Timers.
If we understand correctly, the
broadcast-channeltries to fallback to alternative methods of cross-tab communication in caseBroadcastChannelis not natively supported, e.g. in Safari. The fallback is done in the following order:native -> idb -> localstorage. Having tried to force the usage of alocalstoragemethod by passing{type: "localstorage"}into aBroadcastChannelconstructor, we've got an impression that it fixes the problem of having multiple leader per browsing origin (see the last video in the list above), but taking into account that 1) Safari has a rather controversial reputation when it comes to implementing IndexedDB spec and 2) it lacks a built-in way to monitor changes in a given Object Storeperhaps it makes sense to adjust the order of fallback methods, so that a
localStorageis preferred overIndexedDB, at least in WebKit/Safari.The text was updated successfully, but these errors were encountered: