[IndexedDB] Consider adding some signaling method to notify on the completion of an IDBDatabase.close() operation (#72)

I'm developing a wrapper library for IndexedDB and noticed that on IE11 my tests kept failing due to "operation blocked" errors when a database was closed and subsequently reopened to a higher version number in a quick succession (this is a needed pattern, for example when trying to add a new index to an existing database that is currently open). I've currently resorted to the "primitive" solution of inserting arbitrary timeouts before every reopen operation, e.g:

```js
...
.then(() => {
 if (this.isOpen) {
  this.close();
  return PromiseX.delay(50); // Returns a promise that resolves after a 50ms timeout
 }
}
.then(() => this.open()) // Reopen the database
.then(() => {
 ...
});
...
```
But I can't see that as a permanent solution (in addition to the performance impact there could be cases where even, say, 50ms wouldn't be sufficient and the whole script would essentially crash). I could try a more complex solution like retrying the `open` operation several times thus essentially 'polling' for the close operation end, that might eventually work but would probably become a bit tedious.

It would be very useful if `IDBDatabase.close` would accept a callback or return a Promise that would resolve when the close operation has truly completed, e.g.:
```js
db.close(() => {
  console.log("The database has finally closed! Great! now we can safely reopen it!")
})
// or
db.close()
  .then(() => console.log("A promise could also work here."));
```

**What the docs/specs say**
I'm aware this solution wouldn't really help with old browsers (e.g. IE11) so a workaround would be needed anyway (an idea for a better one would be highly appreciated!). However, I'm not familiar enough with modern browsers implementation internals to know if this would benefit in practice. [MDN says](https://developer.mozilla.org/en-US/docs/Web/API/IDBDatabase/close):
> The connection is not actually closed until all transactions created using this connection are complete. No new transactions can be created for this connection once this method is called. Methods that create transactions throw an exception if a closing operation is pending.

This basically means that some internal process does happen and its completion could be captured as a callback, promise, or some event.

[The spec says](https://www.w3.org/TR/IndexedDB/#dfn-steps-for-closing-a-database-connection):
```
3.3.9 Database closing steps

The steps for closing a database connection are as follows. 
These steps take one argument, a connection object.
Set the internal closePending flag of connection to true. 
Wait for all transactions created using connection to complete.
Once they are complete, connection is closed.

Note
------
Once the closePending flag has ben set to true no new transactions can be created 
using connection.  All functions that create transactions first check the closePending 
flag first and throw an exception if it is true.

Note
------
Once the connection is closed, this can unblock the steps for running a "versionchange" 
transaction, and the steps for deleting a database, which both wait for connections to a given 
database to be closed before continuing.
```
So I guess it could signal when the 'closePending' flag is cleared?

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/IndexedDB/issues/72

Received on Sunday, 20 March 2016 09:39:51 UTC