[whatwg] Offline Web Apps

Aaron Boodman aa at google.com
Thu Sep 13 10:52:07 PDT 2007


On Sep 6, 2007 5:46 PM, Ian Hickson <ian at hixie.ch> wrote:
> We provide an API that can add files to the cache, and that can be queried
> to determine if we are in upgrader mode or not, and that can swap in a
> new cache without reloading the page, during the 'upgrading' event.

Given this, and the hidden context that is used while upgrading (not
the 'upgrader context', just the one that the page you are viewing is
loaded into), isn't it possible to simplify by just doing something
like this?

addFileToCache("otherTopLevelPage.html");
addFileToCache("yetAnotherTopLevelPage.html");
addFileToCache("imageThatWasntReferenced.png");

Then you don't need the manifest anymore, do you?

> Upgrader:
>  Create a hidden browsing context.
>  Load the upgrader in it.
>  Just before onload, fire an 'upgrading' event to every instance of a
>   top-level page using a cache with the same identifier.
>  The event has a handle to the Window object of the hidden browsing
>   context.
>  After every 'upgrading' event has been fired, the 'load' event must be
>   fired on the upgrader.
>  After that happens, if any of the aforementioned instances are still
>   using old versions of the cache, then the user agent may inform user
>   they can reload to update.
>
> The Upgrader can do such things as updating the database schema between
> versions, and when there are multiple instances running, it allows them to
> negotiate who will do that work instead of it happening several times.

I've been thinking about this, and it seems like an interesting idea,
but to me it creates more complexity than it's worth. Here are some of
the questions around it:

* Is an update marked as successful before or after an update runs?
  > If before, the new version of the app must be prepared for the
scenario that the updater did not run completely, in which case you
may as well put the upgrade logic in the new version and be done with
it.
  > If after, how do you track success/failure of the update? Keep in
mind that an update may require asynchronous server access to retrieve
data. If you allow for this, you just add lots of API for a relatively
small case. If you don't allow for it, then in some cases upgrading
will have to be done by the new version of the app.
* I like the idea of app instances being able to talk to each other
during upgrade, but it seems to conflate several goals:
  > Prevent two apps from trying to upgrade at the same time
  > Prevent instances of an app that are old from accessing a newer local schema
  > Allow multiple instances of an app to talk to each other
  > Separate application logic from UI logic and share the application
logic between multiple views (Dimitri and Alex Russell's point)

For the first two problems in gears, we have been kicking around the
idea of versioning the database connections. So you could do:

db.open("mydb", 1);
db.execute(...);
db.execute(...);
..etc..

But as soon as somebody in another window did:

var db.open("mydb", 1);
db.setVersion(2);

The previous connection starts throwing errors. This assumes that the
database has transaction support and a few other things though. From
my point of view this is simpler, but I understand that it relies on
some bits that are not in whatwg's current database proposal.


For the long term, I agree with Dimitri that what is really needed is
a shared JS context between all instances of an application.
Otherwise, anybody that is doing significant synchronization, for
example, will have to somehow organize through all the instances of an
app which page is doing the work. It's silly. We need the ability to
separate an app into the ui bits and the application bit, and have a
one-to-many relationship between them.

If a future version of the spec had something like a gears worker, one could do:

// If the named worker already exists (namespaced to the current
origin I suppose), then a
// reference to it will be retrieved. Otherwise, one will be created.
var worker = getOrCreateWorker("app-logic", "app.js");
worker.sendMessage("load_customers", {account_id: 42}, function(result) {
  result.customers.forEach(function(customer) {
    console.log("Got customer name: %s, id: %d", customer.name, customer.id);
  });
});

- a



More information about the whatwg mailing list