- From: Jonas Sicking <jonas@sicking.cc>
- Date: Tue, 29 Jun 2010 13:40:12 -0700
- To: Jeremy Orlow <jorlow@chromium.org>
- Cc: Webapps WG <public-webapps@w3.org>
On Sun, Jun 27, 2010 at 12:27 AM, Jonas Sicking <jonas@sicking.cc> wrote: >>> >> > But, I feel pretty strongly that a setVersion/schema change >>> >> > transaction >>> >> > should not simply kill off anything else currently running. The >>> >> > reason >>> >> > is >>> >> > that it's not hard for apps to recover from a connection failing, but >>> >> > it >>> >> > is >>> >> > hard to handle a transaction failing in an unpredictable way. >>> >> > Especially >>> >> > static transactions (which should rarely fail committing since >>> >> > serialization >>> >> > can be guaranteed before the transaction starts). >>> >> >>> >> That might be a good idea for v1. I was planning on doing a separate >>> >> thread for setVersion, but maybe it's tied enough to the topic of >>> >> schema changes that it makes sense to bring up here. >>> >> >>> >> What I suggest is that when setVersion is called, we fire >>> >> 'versionchange' event on all other open IDBDatabase objects. This >>> >> event contains information of what the desired new version number is. >>> >> If no other IDBDatabase objects are open for the specific database, no >>> >> 'versionchange' events are fired. This allows pages using the old >>> >> schema version to automatically save any pending data (for example any >>> >> draft emails) and display UI to the user suggesting that the tab be >>> >> closed. If possible without dataloss, the tab could even reload itself >>> >> to automatically load an updated version of the page which uses the >>> >> new schema version. >>> >> >>> >> The 'versionchange' event would use an interface like >>> >> >>> >> interface IDBVersionEvent : IDBEvent { >>> >> readonly attribute string version; >>> >> }; >>> > >>> > First of all, what I was originally advocating (sorry for not being >>> > clear) >>> > is that we should kill the database connection but not until all active >>> > transactions are complete. Though we should probably block new >>> > transactions >>> > from starting once setVersion is called. >>> > But I really like your versionchange event idea regardless. I agree >>> > that >>> > letting the app sync any data that might be in memory (for example, a >>> > draft >>> > email) is important. And the idea that the web app could refresh itself >>> > (or >>> > download new application code or something) seems pretty cool and >>> > useful. >>> > I'm fine with it firing on all frames except the one that initiated >>> > (like >>> > storage events). If we go with the "kill the connection once all active >>> > transactions are done and block new ones from starting", we'd want to >>> > start >>> > the blocking only after all versionchange events have finished. >>> > The main reason that I like the idea of not stating the version change >>> > until >>> > all active connections have closed is that not all apps will handle >>> > versionchange. My original idea was that we should just break such web >>> > apps >>> > and let the user refresh, but now that you've pointed out the potential >>> > for >>> > data loss I'm not sure that's an option. Savvy web apps can kill all >>> > existing database connections when they get the versionchange and thus >>> > avoid >>> > stalling things. >>> > >>> >> Additionally, if there are open IDBDatabase objects, we fire a >>> >> 'blocked' event at the IDBRequest object returned from the setVersion >>> >> call. This allows the page to display UI to the user asking the user >>> >> to close all other relevant tabs. >>> >> >>> >> Once all other IDBDatabase objects are closed, we create a transaction >>> >> and fire the normal 'success' event. >>> >> >>> >> While there are pending version change requests, no success events are >>> >> fired for calls to IDBFactory.open for the relevant database. >>> >> >>> >> We might want to support forcefully killing off open IDBDatabase >>> >> objects in the future, but I think that can wait until after v1. >>> > >>> > Really? I can't see an app like gmail ever asking users to close tabs. >>> > I >>> > bet they'd sooner run all the application logic in an iframe and >>> > navigate it >>> > away when doing a schema change. >>> > And I don't see many people correctly implementing a blocked event >>> > handler. >>> > If anything, it should be an error code. >>> > It doesn't seem that hard to have an explicit way to tell the database >>> > explicitly "OK, I'm done". Or, at very least, we could make it so that >>> > when >>> > there's an existing setVersion happening, all new connection requests >>> > stall. >>> > That way all pages can reload themselves but they won't connect to the >>> > database until the upgrade is complete. >>> > But really...all of this is really hacky. I'm starting to wonder if we >>> > should just kill the database connections on a setVersion as I >>> > originally >>> > tried to suggest. >>> >>> I'm pretty concerned though that sites will need to take asynchronous >>> actions in order to save all required data. While gmail happily >>> automatically saves every few minutes, and presumably could >>> immediately do so upon a 'versionchange' event, I don't think all >>> editors are willing t. For example many editors ask the user if they >>> want to save the current changes when they are closed, in order to not >>> overwrite correct data. >>> >>> Additionally, there is always the risk that developers will forget to >>> use a versionchange event handler to protect their data. I think a >>> good design principal is that if sites do the minimal amount of work, >>> that should default to safe behavior. >>> >>> I do realize that not all applications are willing to do the "please >>> close all other tabs" UI thing. But for those we would provide enough >>> tools do something better. If we add a IDBDatabase.close() function >>> then applications that can easily emulate the "force-close open >>> connections" using that and the versionchange event. And they could >>> even use that to implement asynchronous data saving for when that is >>> required. >> >> Yeah. I think giving developers a .close() (or maybe even a >> .closeOthers()?) should be enough. It still feels clunky to me, but I also >> think it'd be dangerous to over-design this without some feedback from >> several developers using this in the real world...which won't happen until >> we ship something (even if its basic). > > Ok, I'll file a bug. Filed http://www.w3.org/Bugs/Public/show_bug.cgi?id=10052 Please check that I documented the right thing. I wasn't sure if we decided to move createObjectStore/removeObjectStore to a new type of transaction or not. I kept it on IDBDatabase for now since we can't move createIndex/removeIndex anyway. / Jonas
Received on Tuesday, 29 June 2010 20:41:06 UTC