wikitree / wikitree-browser-extension

Browser extension that adds advanced features to WikiTree.com.
MIT License
24 stars 20 forks source link

Upgrade from v3 of the CC7Database to v4 sometimes require a browser restart #566

Open udjeni opened 4 months ago

udjeni commented 4 months ago

Describe the bug In WBE Preview v1.16.8.1, it was necessary to upgrade the CC7Database to a new version. Unfortunately this upgrade sometimes require a restart of the browser and not just a refresh of the page. It seems the requirement of a restart is triggered if the user has at some point restored their CC7Database from a backup file.

To Reproduce Steps to reproduce the behaviour:

  1. Load a WBE before Preview v1.16.8.1 (or before this PR: https://github.com/wikitree/wikitree-browser-extension/pull/565)
  2. Ensure that distance and relationships are enabled under the Profile settings of WBE
  3. Create a backup of your WBE data by going to your WT "My Navigation "home page and clicking the "Download WBE Feature Data". NOTE: if you are running the stable WBE, you may have to do the backup from the WBE setting menu.
  4. Go to one of your direct ancestor profiles.
  5. Now use the Inspector to delete the following indexedDB databases: CC7Database, ConnectionFinderWTE, and RelationshipFinderWTE.
  6. Refresh the above profile page so all three DBs are recreated and populated (refreshing the Nav home page is not enough to create the latter 2 DBs)
  7. Now load WBE Preview v1.16.8.1 and refresh the profile page.

Everything should work - you should still see the distance/relationships added to the profile and under the Find menu there should be "CC7 Changes"

Now repeat the above steps, but add step 6a: restore your WBE data from the backup. After the subsequent upgrade, distance/relationships will still be there, but not the CC7 Changes button. It will only appear after a restart

Desktop:

Additional Context In the file cc7_changes.js in the method Database.initializeDB, around line 206 there is a statement const openRequest = indexedDB.open(CC7_DB_NAME, 4); followed by setting up the callbacks openRequest.onupgradeneeded, openRequest.onsuccess, and openRequest.onerror. Testing showed that in the refresh after step 6a, we get to this open statement, but then none of the on... callbacks are called. Should you at this point delete the CC7Database the onerror callback is called with something like "connection closed".

The question is what is the difference between this code and the DB upgrade code in distanceAndRelationships.js, which follow the same pattern, but does not have the same issue?

udjeni commented 4 months ago

The reason for what we see above might be related to what is described under "Parallel update problem" in https://javascript.info/indexeddb, namely

The problem is that a database is shared between two tabs, as it’s the same site, same origin. And it can’t be both version 1 and 2. To perform the update to version 2, all connections to version 1 must be closed, including the one in the first tab.

In order to organize that, the versionchange event triggers on the “outdated” database object. We should listen for it and close the old database connection (and probably suggest a page reload, to load the updated code).

If we don’t listen for the versionchange event and don’t close the old connection, then the second, new connection won’t be made. The openRequest object will emit the blocked event instead of success. So the second tab won’t work.

Solutions for fixing the above is also given in the same section (i.e. add db.onversionchange and db.onblocked handlers.