jakearchibald / idb

IndexedDB, but with promises
https://www.npmjs.com/package/idb
ISC License
6.31k stars 356 forks source link

dbPromise never returns in certain circumstances... #148

Closed onzag closed 4 years ago

onzag commented 4 years ago

Reproduction steps are simple:

const version = 1;
const DB_NAME = "RANDOM";
const TABLE_NAME = "Tabla"
this.dbPromise = openDB<ICacheDB>(DB_NAME, version, {
    upgrade(db) {
      try {
        db.deleteObjectStore(TABLE_NAME);
        const queriesStore = db.createObjectStore(TABLE_NAME);
        queriesStore.createIndex("expires", "timestamp");
      } catch (err) {
        console.warn(err);
      }
    },
  });

await this.dbPromise;

How to reproduce.

  1. Open a window.
  2. Change version to 2.
  3. Open another window.

The second window will be stuck forever until the first window releases the database.

I need a way to know if this is happening because otherwise my app gets stuck loading forever.

I would rather force the older the cache to open and force the old window to release, or in the worst case scenario, just my current window to fail to get the database, but not to just get stuck loading forever.

jakearchibald commented 4 years ago

See the blocked() and blocking() callbacks https://github.com/jakearchibald/idb/blob/master/README.md#opendb

They tell you when this is happening, and you can choose to close your connection in response.

onzag commented 4 years ago

Sorry for the delay but how does exactly the function allow me to release the connection?... I thought that a blocking event would cause an error, or at least the promise would release; awaiting the function forces me to have to release the connection or otherwise I will have a forever waiting promise which because it does nothing, and it doesn't time out which hangs the entire application, that is a danger, specially if it fails to unblock.

Would using the "blocking" and db.close guarantee always that the promise is released?... at least with an error? My only fear is that it would hang.

jakearchibald commented 4 years ago

I'm not sure what "release the promise" means.

If your connection is blocking another, and you call db.close(), it will close that connection and unblock others.