Re: IndexedDB: IDBOpenDBRequest sequencing

On Fri, Dec 21, 2012 at 11:26 AM, Joshua Bell <jsbell@chromium.org> wrote:
> I was playing around with the following sample:
>
> <!DOCTYPE html>
> <script>
>   var dbname = 'db' + Date.now();
>   function show(m) { return function() { console.log(m); }; }
>   openRequest1 = indexedDB.open(dbname, 1);
>     openRequest1.onblocked = show("openRequest1 - blocked");
>     openRequest1.onsuccess = function() {
>       console.log("openRequest1 - success");
>
>       openRequest2 = indexedDB.open(dbname, 2);
>       openRequest2.onblocked = show("openRequest2 - blocked");
>       openRequest2.onsuccess = show("openRequest2 - success");
>
>       deleteRequest = indexedDB.deleteDatabase(dbname);
>       deleteRequest.onblocked = show("deleteRequest - blocked");
>       deleteRequest.onsuccess = show("deleteRequest - success");
>
>       openRequest3 = indexedDB.open(dbname);
>       openRequest3.onblocked = show("openRequest3 - blocked");
>       openRequest3.onsuccess = show("openRequest3 - success");
> };
> </script>
>
> In both FF17 and IE10 the output is:
>
> openRequest1 - success
> openRequest2 - blocked
>
> If you manually execute openRequest1.result.close() the output continues:
>
> openRequest2 - success
> deleteRequest - blocked
>
> Finally, if you manually execute openRequest2.result.close() the output
> concludes:
>
> deleteRequest - success
> openRequest3 - success
>
> Given the spec, I would have expected that deleteRequest's blocked event
> would be fired immediately when the script was executed rather than waiting
> until the first connection was closed. The second open() call should follow
> the steps in 4.1 "Opening a database" through 6 ("Create a new connection to
> db..."), then in step 7 jump to 4.8 "steps for running a versionchange
> transaction", resulting in a blocked event at step 3, and in step 4 waiting
> until the first connection closes. So far so good. But in 4.11 "Database
> deletion steps" I don't see anything preventing the steps from starting or
> proceeding through step 6, resulting in a blocked event.
>
> As written, I would expect this behavior:
>
> openRequest1 - success
> openRequest2 - blocked
> deleteRequest - blocked
>
> i.e. the second open creates a connection but the versionchange must wait so
> "blocked" is fired;

Agreed so far.

> the delete call sets the delete pending flag, but must
> also wait so "blocked" is fired. The third connection must wait since the
> delete pending flag is set, so it waits (silently) at 4.1 step 3.

I agree that this is what the spec says, but this seems like a spec
bug to me. I'd prefer is the "blocked" event was always fired if the
"success" event is hindered due to someone keeping the database open.
I.e. we should only wait silently there if all open connections to the
database (if any) have the closePending flag set.

> If you manually execute openRequest1.result.close() the second connection's
> versionchange can proceed, leading to:
>
> openRequest2 - success
>
> Finally, if you manually execute openRequest2.result.close() there are no
> more connections so the delete can proceed. Once the delete has completed
> the third open can proceed, leading to:
>
> deleteRequest - success
> openRequest3 - success
>
> I'd chalk this up to browser bugs, but the identical behavior in FF17 and
> IE10 gives me pause. One way to model this behavior would be to imply that
> only one IDBOpenDBRequest (either an open or a delete) can be running
> against a database at a time. I don't see this stated in the spec, but it's
> a reasonable model.
>
> Can implementers speak up on their interpretations of the spec? Do we need
> to clarify the spec here one way or another?

The current Firefox behavior definitely seems like a bug to me.

I think that the proper set of events is either

openRequest1 - success
openRequest2 - blocked
deleteRequest - blocked
openRequest3 - blocked

or

openRequest2 - success
deleteRequest - blocked
openRequest3 - blocked
openRequest1 - error

Note that the spec already says that if two requests to open the same
database, but with different versions, happens "at the same time" then
the one with the higher version number is attempted to be opened first
and if that's successful the one with the lower numbers receives an
error.

See the Notes in 4.1 step 3.

"at the same time" is of course hard to define.

/ Jonas

Received on Wednesday, 27 February 2013 01:03:00 UTC