New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Soft Update and Register can race when setting registration scriptURL #789
Comments
Or alternatively, maybe the soft update should not run if it sees the registration script URL is different from the newest worker script URL. In that case its clear a new script is being registered and no update is needed. |
Yea, I'm going to implement this change. In Soft Update, instead of:
Instead do:
|
Actually, the whole Algorithms like Register, Soft Update, and Update all do:
Where X is either the register() script URL or the newestWorker's script URL. After running this step these algorithms all then invoke Update. This is a problem because Update uses a queue to perform operations. So the actual work is often (usually) done asynchronously from where the script URL is set up. This means the work performed by the Update can easily operate on the wrong registering script URL. I think the registering script URL should really be an argument to Update. The source of current truth for the registration's script URL should be the newestWorker.scriptURL. |
To clarify, I propose:
Then Register algorithm passes the content provided script URL to the Update algorithm. The update() and Soft Update algorithms do not pass a script URL to the Update algorithm, and therefore get the default "newest worker" script URL. And in the Register algorithm, change step 4.2.3 from
To just:
|
@mattto What does chrome actually do here? I suspect the spec doesn't describe the chrome behavior accurately. It would be nice to sync to that if we can. |
In Chrome, register jobs triggered by register(script_url) are marked with script_url when scheduled, and update jobs triggered by Soft Update or update() are marked with the newest worker's URL when scheduled. When an update job runs, if the newest worker's URL has changed from the one the job was marked with, it aborts. When a register runs, if the newest worker's URL has NOT changed, the job aborts (usually... if the registration was uninstalling it cancels that and it can also promote waiting -> active if there's no active worker but that's an impl detail). Otherwise, it performs an update with the script URL it was marked with. I think that's almost what you propose, except that in your proposal update job wouldn't be marked with a URL when scheduled, and would instead simply take the newest worker URL once the job actually begins. |
I understood the problem pointed by @wanderview. Mutating the registration's registering script url from the concurrently running main threads (Register, update(), Soft Update) shouldn't be allowed. Marking a url for an Update from @matto's comment seems to be able to be specified as passing an argument to Update algorithm as @wanderview suggested as that's the place where the job is scheduled. I think we still have to decide between 1) Blink's behavior: schedule and abort when newest worker's url was changed and 2) Gecko's suggestion: use newest worker's url when job begins for update jobs. @wanderview will it be okay to conform to what Blink already implemented for this? If so, the Update algorithm can take a script url as a (non-optional) argument and check if the given url is the same as the newest worker's script url before continuing with further steps. I'll address the decision once I'm back to work. |
I'm happy to accept blink's behavior here. Thanks! |
@matto, does this match the current spec:
As far as I can tell the spec says that the check for matching URL should run synchronously when .register() is called. We also defer it until the job runs, but I have a bug open to fix that. |
I think you're right, the spec says it should run synchronously when .register() is called. As a general note, differences like this are artifacts of how Chrome implemented a register/update/unregister job queue before the spec had them defined (lots of discussion was at #396 ). Chrome should probably fix these but I suspect they are minor differences. |
To be honest, I think we should change the spec on this one. I don't like that .register() accesses shared state outside of the job queue synchronization mechanism. See issue #783. |
I'll take a look how I can address this requirement. Seems like some refactoring is needed in Register and Update. |
Merged to #783. |
Consider the following sequence of events.
There is now a race between:
If the navigation soft update triggers prior to the register's update job getting popped from the queue then the registrations scriptURL is reset to script1.js.
Why does soft update reset the registration's script URL? It seems using the current registration script URL is probably what we want. This is the solution I am going to implement in gecko for now.
The text was updated successfully, but these errors were encountered: