This seems like a pretty bizarre solution. Careful design of updates to be resilient to ordering errors seems like the appropriate response here -- for instance, using the remote site like a content-addressible cache, rather than a name-addressible cache.
In response to a cache that provides only bare minimums for functionality, the author seems to be suggesting throwing away all the the cache logic that browser vendors have gone to implement for you, and instead rewriting one's own cache atop LocalStorage and IndexedDB. This seems like a pretty concerning reaction -- or am I simply misreading the author's conclusion?
What he means is, instead of having a file you name
myscript.js
you name it
myscript-[sha1 hash of contents].js
and you set its cache header to expire at some improbably point in the far far future. If you should happen to update the contents of your script file- the sha1 hash will change, and thus its name and its cache entry will also change, in lockstep with its contents. The only fiddly part of this approach is you must also update all references to the new version of the file. If you're clever you can automate this with templates and build systems.
What this guarantees is that if your index.html and app cache manifest refer to myscript-[some specific sha1], you're guaranteed that the contents of the script are consistent with what that index.html file expects there.
Yes, that's standard deployment practice, but unfortunately with appcache, nothing links index.html to any specific version of the manifest. You can't even query it to see what version of the manifest you have. So you can end up with index.html trying to include a script of hashv1.js, but manifest has hashv2.js.
This can happen if clients are updating to app version 2 just as you are deploying v3. It's totally racy.
EDIT: I have a python script that proves it. It basically does new deployments (using only new, versioned .js files) while the browser reloads. I will be updating the post in the near future.
EDIT: Post updated with the test script and screenshot of what blows up.
what if the manifest.appcache is content addressable ?
e.g. manifest-[version-number].appcache
the appcache semantics are convoluted enough that I must admit I don't know what would happen. Would you visit index.html and it loads the old version of index.html linking to the old version of the cache manifest-- forever?
Perhaps the old version of the manifest gets a comment incremented to force the browser to update index.html?
or some tricky javascript forces it?
Either way it seems, naively like you could link an index.html version to a manifest version via the manifest's filename.
Comments
This seems like a pretty bizarre solution. Careful design of updates to be resilient to ordering errors seems like the appropriate response here -- for instance, using the remote site like a content-addressible cache, rather than a name-addressible cache.
In response to a cache that provides only bare minimums for functionality, the author seems to be suggesting throwing away all the the cache logic that browser vendors have gone to implement for you, and instead rewriting one's own cache atop LocalStorage and IndexedDB. This seems like a pretty concerning reaction -- or am I simply misreading the author's conclusion?
Do you mind elaborating on content addressable vs name addressable? I did a quick google search on "name addressable cache" and did not find anything.
What he means is, instead of having a file you name
you name it and you set its cache header to expire at some improbably point in the far far future. If you should happen to update the contents of your script file- the sha1 hash will change, and thus its name and its cache entry will also change, in lockstep with its contents. The only fiddly part of this approach is you must also update all references to the new version of the file. If you're clever you can automate this with templates and build systems.What this guarantees is that if your index.html and app cache manifest refer to myscript-[some specific sha1], you're guaranteed that the contents of the script are consistent with what that index.html file expects there.
Yes, that's standard deployment practice, but unfortunately with appcache, nothing links index.html to any specific version of the manifest. You can't even query it to see what version of the manifest you have. So you can end up with index.html trying to include a script of hashv1.js, but manifest has hashv2.js.
This can happen if clients are updating to app version 2 just as you are deploying v3. It's totally racy.
EDIT: I have a python script that proves it. It basically does new deployments (using only new, versioned .js files) while the browser reloads. I will be updating the post in the near future.
EDIT: Post updated with the test script and screenshot of what blows up.
what if the manifest.appcache is content addressable ? e.g. manifest-[version-number].appcache the appcache semantics are convoluted enough that I must admit I don't know what would happen. Would you visit index.html and it loads the old version of index.html linking to the old version of the cache manifest-- forever?
Perhaps the old version of the manifest gets a comment incremented to force the browser to update index.html? or some tricky javascript forces it? Either way it seems, naively like you could link an index.html version to a manifest version via the manifest's filename.
I see what you mean. But, at this point I'm not really interested in dicking around with it any more :-)