Skip to content
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

Update mechanisms #26

Closed
lidel opened this issue Feb 21, 2024 · 6 comments · Fixed by #100
Closed

Update mechanisms #26

lidel opened this issue Feb 21, 2024 · 6 comments · Fixed by #100
Assignees

Comments

@lidel
Copy link
Member

lidel commented Feb 21, 2024

Need

At some point we may want to not reload worker on every page load(?).

We may have a bug which breaks all websites, there may be an important update, or user wants to ensure they have the latest version.

We need reliable mechanisms for forcing reload of SW code.

Implementation ideas

Below are my initial ideas, feedback welcome.
I think at minimum, at least short term, we need (A) and (C).

Global:

  • (A) lo-fi time-bomb: expire worker after some time, force-reload every 24h (at least while we have intensive dev)
  • (B) DNSLink beacon checked on each load
    • we could inspect /ipns/inbrowser.link/sw-version on sw init, and if set to timestamp/version higher than one in sw code, we force-reload sw to new version.

Per user:

  • (C) a ?sw-update param, allows end user to manually force reload
  • (D) we could use ServiceWorkerRegistration.onupdatefound it on root domain to softly inform user new version is available, and button they could click to update + have cookie that then informs all subdomains to update as well.
@SgtPooki
Copy link
Member

related: #96 (comment)

@SgtPooki
Copy link
Member

At some point we may want to not reload worker on every page load(?).

Currently, once a SW is registered on the subdomain, the subdomain SW never gets an update unless the user explicitly deletes it. see #96 for catching sw-only-asset requests

@2color
Copy link
Contributor

2color commented Mar 11, 2024

Based on the following docs, the browser checks for byte changes to the SW script on "navigation to an in-scope page.", but I'm not sure what's exactly meant by "in-scope page".

Does that mean that every time CID.ipfs.inbrowser.link is loaded after the SW has been installed, the browser will check for changes or is it only if pages are served from the actual UI rather than the service worker?

Also somewhat relevant for this: https://stackoverflow.com/questions/33986976/how-can-i-remove-a-buggy-service-worker-or-implement-a-kill-switch/38980776#38980776

@SgtPooki
Copy link
Member

SgtPooki commented Mar 11, 2024

Does that mean that every time CID.ipfs.inbrowser.link is loaded after the SW has been installed, the browser will check for changes or is it only if pages are served from the actual UI rather than the service worker?

it means that CID.ipfs.inbrowser.link/sw.ts is checked by the browser, and downloaded. Currently (i.e. without #96) this fails because the sw is unaware of it's own assets, and it never can update. Basically, the SW forwards all requests to helia/verified-fetch.. for the CID of the subdomain.. and "sw.ts" does not exist in that root. This is why I want to change the names to have "ipfs-sw" prefix or other unique-enough prefix so SW will ignore these, and it will pass through to the root SW site CID (i.e. request makes it to the server)

every service worker is registered to a scope. For our usecase: an origin. But it can also be an origin+path for service workers in general.

Does that mean that every time CID.ipfs.inbrowser.link is loaded after the SW has been installed, the browser will check for changes or is it only if pages are served from the actual UI rather than the service worker?

the browser checks for changes after 24 hours or .. other things. But we have code in the UI that will automatically update the SW. The problem is, on subdomains, the UI is never rendered (currently) beyond the #/ipfs-sw-config added in #96

@SgtPooki
Copy link
Member

I don't like the idea of A if we have C, but I can implement A and C,

Both will use some version of this function:

async function deregister() {

	self.registration.unregister()
	    .then(function() {
	      return self.clients.matchAll();
	    })
	    .then(function(clients) {
	      clients.forEach(client => client.navigate(client.url))
	    });
}

A details:

on install: Add a timestamp to existing config-db.
on fetch handler: check if timestamp is over 12hr, if so, call deregister

C details

// <sw-host>/#/ipfs-sw-unregister
// in fetch lifecycle event:
if (isDeregisterRequest(event)) {
  event.waitUntil(deregister())
  return
}

@SgtPooki SgtPooki self-assigned this Mar 12, 2024
@SgtPooki
Copy link
Member

Note that #96 should mostly handle stale service workers. However, since the SW asset name changed in #97, current users may need to remove the service worker forcefully (since we don't have an implode option on the previous service worker)

@SgtPooki SgtPooki linked a pull request Mar 12, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants