IndexedDB: IDBOpenDBRequest sequencing

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; 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.

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?

Received on Friday, 21 December 2012 19:26:53 UTC