Open Bug 1474727 Opened 2 years ago Updated 8 months ago
Consider making runtime
.connect and runtime .send Message wait for background page startup unconditionally
When a web extension first installs, there is currently no way to guarantee that the background script loads before a content script. This means it's possible that a content script tries to make a connection via `browser.runtime.connect` before the `browser.runtime.onConnect` listener in the background script is present. This race condition happens reliably, for example, when a page is already loaded before the web extension is installed. The current workaround for this is to listen for the `onDisconnect` event in the content script if/when the connection fails and retry (perhaps after a short pause). It would be great if we could guarantee the connection/message in this situation is always successful on install, like it is on subsequent startups.
Hi Bianca, this sounds like Bug 1378459, are you able to reproduce with the the preference extensions.webextensions.background-delayed-startup is true? (on Nightly this pref is already set to true by default, and Bug 1473757, which has been landed recently, will make it enabled for the other channels).
As mentioned in comment 0, this bug is about the race between content scripts and the background page that happens when an extension is installed, not what happens during browser startup. The logic for blocking messages to the background script during browser startup relies on knowing that there was an onConnect or onMessage listener from a previous browser session, but off the top of my head, I think it should be reasonably straightforward to apply the same logic when an extension is activated at some time after browser startup.
Component: Add-ons Manager → General
Product: Toolkit → WebExtensions
I’ve also run into this quirk. For me, content scripts for already existing tabs are run before background scripts 100% of the time and messaging fails until the background scripts are loaded. (Firefox Nightly 63.0a1 (2018-09-02) (64-bit)) As far as I can tell, bug 1369841 should have fixed this (at least bug 1369841 comment 2 sounds exactly like what’s being described here), but I might be misunderstanding what that bug is about. I added a comment there (comment 1369841 comment 36) about the bug being present in Firefox 63, but was asked to open a new issue (bug 1369841 comment 37). When starting to do so, I found this bug. So here goes. Just in case you need more test cases, I’ll chip in with some extra information. Basically, the example here does not work for already open tabs: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/connect#Examples Here’s a minimal extension demonstrating the problem: https://github.com/lydell/webext-message-issue Here’s how I work around it in the extension I’m building: https://github.com/lydell/synth/blob/cea63e1658be6d03013bf97860f60567010c1cba/src/renderer/Program.js#L107-L120 https://github.com/lydell/synth/blob/cea63e1658be6d03013bf97860f60567010c1cba/src/renderer/Program.js#L154-L160 https://github.com/lydell/synth/blob/cea63e1658be6d03013bf97860f60567010c1cba/src/background/Program.js#L121-L129 The first thing I do in the content scripts is to send a message to the background, saying that the content script is alive (they need to sync state with each other). The steps look like this: 1. Try to send the Startup message from content to background. 2. If that succeeds—great, nothing more to do! If that fails, ignore the error and wait for the Workaround message. 3. During the startup phase of the background script, get all open tabs where the content script should run and send a Workaround message. 4. Receive the Workaround message in the content script and re-send the Startup message from content to background. But ideally the steps would just be: 1. Send the Startup message from content to background. Done.
Priority: P2 → P3
You need to log in before you can comment on or make changes to this bug.