Steve
October 9, 2019
When you visit debugger.nerd.vision, we wait until some critical dependencies are loaded before we render the UI. Users see this as the NV logo flashing on screen before the actual application loads. These dependencies range from getting the current users information, to setting up IndexedDB ready to handle our in browser caching.
We recently encountered an issue on debugger.nerd.vision where the site would occasionally get stuck attempting to resolve these dependencies. After a quick check, we noticed that the calls to the API were all handled successfully, leaving IndexedDB as the issue. But we’d seen no errors on our bug tracking solution, and on the occasion that one of our support team managed to reproduce this, there was nothing obvious in the browsers developer console.
For those of you that are unaware, IndexedDB requires you to set up handlers for certain situations: onsuccess, when the connection to IndexedDB is established; onerror, when an error happens; onupgradeneeded, when the database is out of date and needs to be updated; and onblocked, when the IndexedDB upgrade is blocked by another connection. None of these were fired when the page refused to load.
After some more research, we figured out that there was another event which needed to be handled: onversionchange. This event is available in the onsuccess event as it’s intended to handle another connection of IndexedDB trying to upgrade or delete the database while we’re still connected. What this allows us to do close our connection so it no longer blocks their connection.
const baseDB = window.indexedDB.open('nv-db', 1);
baseDB.onsuccess = event => {
const db = event.target.result;
db.onversionchange = () => {
db.close();
};
};
What counts as another connection? Every time you open an IndexedDB database, that creates a connection. One of the more common situations where you get multiple connections is when a user opens the application in multiple browser tabs. It turns out this was our issue, our user had two instances of debugger open in different tabs. When logging out and then logging back in, they’d be met with a blank screen as the other tab was still connected and blocking the database setup.
After implementing the onversionchange handler to close the database connection, we need to reconnect to the database so that the user can continue to use the cache. In our case we only delete the database on logout, so asking the user to refresh the page to get the latest information was an easy solution. This ensures that they’ll either be redirected to login, or get the new session information if they’ve logged in on another tab.
In conclusion, this is a good example of why it’s good to read through all the documentation for a product to ensure that you aren’t missing any edge cases. A simple missing event and DB close could, in certain situations, cause our application to visibly fail, damaging a users experience.
I'm a Software Engineer on the nerd.vision team. My skills mostly lie in the UI/Node area, but I also work with the backend services.