Skip to content
This repository has been archived by the owner on Nov 27, 2018. It is now read-only.

support an app update user flow #5

Open
mykmelez opened this issue Sep 17, 2015 · 13 comments
Open

support an app update user flow #5

mykmelez opened this issue Sep 17, 2015 · 13 comments
Assignees

Comments

@mykmelez
Copy link
Contributor

Oghliner should support an app update user flow, so an app that uses Oghliner receives a message when an update is available and can prompt the user to update the app (if it chooses to do so, and at the appropriate time).

The flow would be optional, so an app that wants updates to be completely automatic and silent can simply ignore the message and never prompt the user to update the app, which will then update itself automatically whenever the service worker is updated by the browser (which is currently the default and only supported flow).

See sw-precache's demo service-worker-registration.js file for inspiration, but ideally we would not have apps add their custom logic to our own equivalent (service-manager.js) but rather expose the registration to their code in a way that makes it possible for them to listen for its events and handle them in their own script.

@mykmelez
Copy link
Contributor Author

mykmelez commented Nov 2, 2015

@delapuente I wonder if this is something that will be easier to do with offliner than with sw-precache.

@delapuente
Copy link
Contributor

According to the offliner model, when an update is available (the case for oghliner, as soon as the worker changes), an evolve strategy executes (this case a reinstall is taking effect) and an activationPending is issued to the client. The activation swap the offline caches.

The default behaviour for oghliner mimics what is implemented now so, we listen to activationPending and reload but we could default into simply ignore the signal and show a tip for implementation and add the reload only if the developer use the option --on-update reload or something like this. The opposite is interesting as well, autoreload by default providing a complete sample lifecycle and use some like --on-update ignore to manually handle the activation.

@marco-c
Copy link
Contributor

marco-c commented Nov 3, 2015

So by using offliner (#96) we basically get this for free (because the user can define his update strategy), don't we?

@delapuente
Copy link
Contributor

Yep, you have the current implementation here: https://github.com/mozilla/oghliner/pull/96/files#diff-1e6990c753cb6c767172ea5f54207c2fR6

@mykmelez
Copy link
Contributor Author

mykmelez commented Nov 3, 2015

So by using offliner (#96) we basically get this for free (because the user can define his update strategy), don't we?

If so, then it may be that the only thing to do here, once #96 lands, is to document the support for an app update flow. But I want to make sure that the flow we get with #96 is the one described by this issue, in particular (from the original description):

Oghliner should support an app update user flow, so an app that uses Oghliner receives a message when an update is available and can prompt the user to update the app (if it chooses to do so, and at the appropriate time).

Also:

Yep, you have the current implementation here: https://github.com/mozilla/oghliner/pull/96/files#diff-1e6990c753cb6c767172ea5f54207c2fR6

If I read that code correctly, it automatically reloads the page when an update is available. That's a valid option, but my intent in this issue is to describe a flow that by default does not reload the page but rather updates the app the next time the page is reloaded:

The flow would be optional, so an app that wants updates to be completely automatic and silent can simply ignore the message and never prompt the user to update the app, which will then update itself automatically whenever the service worker is updated by the browser (which is currently the default and only supported flow).

I realize, upon rereading that sentence, that the intent wasn't completely clear! In any case, I do think the developer should have the option to instantly reload the page (or prompt the user to reload it) by observing an event that indicates that an update is available, which is the third part of the description:

See sw-precache's demo service-worker-registration.js file for inspiration, but ideally we would not have apps add their custom logic to our own equivalent (service-manager.js) but rather expose the registration to their code in a way that makes it possible for them to listen for its events and handle them in their own script.

Can offliner support a flow in which updates are automatic, silent, and patient (awaiting a reload, not causing one) by default but can be configured to be loud and/or impatient by the developer?

@marco-c
Copy link
Contributor

marco-c commented Nov 3, 2015

Can offliner support a flow in which updates are automatic, silent, and patient (awaiting a reload, not causing one) by default but can be configured to be loud and/or impatient by the developer?

With #96 the developer has the possibility to configure its own update strategy, with the default being reload. So, I think after #96 lands, we only need to change the default (or change it directly in #96).

@delapuente
Copy link
Contributor

I got your point Myk. I see the need of changing the manager in such a way oghliner exposes a custom event to update. Not the one originally exposed by offliner because offliner must be an implementation detail.

@delapuente
Copy link
Contributor

I have some concerns about the patience update flow. Let's state our goal: once we know there is a new version available, we don't want to update until the page is reloaded. In this context, update means to start serving the new contents (please, correct me if I'm wrong here).

Let's consider how updating a service worker works. When an update is found, it enters installing state triggering install event. Once done, it progresses to installed state and keeps waiting until all clients are closed. Then, when reloading the webpage, the new worker enters activating, then activated where it starts to attend fetch events.

With this default behavior we get our patient update flow for free. But this is not what sw-precache is providing as it uses skipWaiting() and claim() so the worker gets active without waiting for clients to be closed. This skip & claim pattern is implemented in offliner as well.

At a first glance, the skip & claim pattern prevents the patient flow to be implemented at all. But there is a workaround for offliner specifically. In both cases of sw-precache and offliner, they give you the opportunity to know when a new update is available but in the case of sw-precache, after installing, the worker will be no longer serving the out of date resources as it deletes them during installation. In the other hand, offliner did not remove the previous content yet and it continues serving the old content until calling offliner.activate() explicitly.

So, here is the idea to implement the patient flow: on activationPending event from offliner, let's register a handler for the unload event that instructs offliner to activate the new version.

What could go wrong? Well, several things. The main problem of this approach is the browser crashing so the webpage won't trigger the unload event but this can be considered a corner case. The other problem is that instructing an activation is an asynchronous operation and closing the page will happen after processing unload handlers so I'm not totally sure the activation message will reach the service worker. We should try.

What is sure is that sw-precache has removed the older content and it's serving the new content. That makes sense for the kind of static assets sw-precache was intended to deal with and it's something totally feasible for offliner as well (simply activate on activation pending but not reload). Other solutions involves disabling the skip & claim pattern to make the patient flow the natural option.

@marco-c @mykmelez what do you think?

@mykmelez
Copy link
Contributor Author

mykmelez commented Nov 3, 2015

Other solutions involves disabling the skip & claim pattern to make the patient flow the natural option.

This seems like the better solution, as it's more robust and works with the Service Worker API rather than around it. Of course it does require modifying offliner, but it seems like something that could be turned into a configurable option in a straightforward manner.

@marco-c
Copy link
Contributor

marco-c commented Nov 4, 2015

@delapuente Could we define a default update strategy that implements the patient flow without modifying the offliner source? From the documentation (https://github.com/delapuente/offliner#updating), it seems feasible.

@delapuente
Copy link
Contributor

I spent all the day thinking how and I discovered a couple of flaws in offliner. I'm still thinking how.

@delapuente
Copy link
Contributor

Well, I finished implementing the integration. I'm going to file a couple of bugs in offliner, rebase, make the tests to pass and ask for review again. I opted for implementing the patient flow with the on unload approach as it does not force me to change the general behaviour for offliner. Thew new patch won't fix this issue. We still need to expose activation to the user but let's do it in another pull request.

@mykmelez
Copy link
Contributor Author

I still think we should do this, but I no longer think we should do it in v1, as it needs more thinking, and it isn't significant enough to hold us back from shipping the rest of the valuable features in v1. So I'm going to remove it from the v1 milestone, and then let's continue to think about how best to do this.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants