Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Web] calling WasmProbeResult.deleteDatabase() with more than one tab open never completes #3460

Open
miguelcmedeiros opened this issue Feb 7, 2025 · 3 comments

Comments

@miguelcmedeiros
Copy link

When running an app on Web on multiple tabs, calling WasmProbeResult.deleteDatabase() never completes. If this is called with a single tab, then it completes properly.

The exception is thrown:

InvalidStateError: Failed to read the 'error' property from 'IDBRequest': The request has not finished.
package:drift/src/web/wasm_setup/shared.dart 440:31                               <fn>
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 598:37  _checkAndCall
dart-sdk/lib/_internal/js_dev_runtime/private/profile.dart 117:39                 dcall
package:web/src/helpers/events/streams.dart 165:63                                <fn>
dart-sdk/lib/_internal/js_dev_runtime/patch/js_allow_interop_patch.dart 224:27    _callDartFunctionFast1

It attempts to complete the request with error (which is not set) when it receives a blocked event for IDBVersionChangeEvent. Even then the blocked event does not complete with an error, the success event never arrives.

Trying to call WasmProbeResult.deleteDatabase() to delete it when database corruption is detected, but once there are multiple tabs open, the database recovery (i.e. detect database corruption, delete it and recreate it) gets stuck.

@simolus3
Copy link
Owner

simolus3 commented Feb 7, 2025

I can reproduce the issue, but I'm not sure what the right behavior would be here. As you said, ignoring the blocked event when deleting databases causes the future to never complete.

So, what do we do about this? We can make other tabs close their databases when they detect a tab trying to delete a database. The consequence is that other tabs would then report database errors until they too try to re-open their database.
So it seems to me that deleting an IndexedDB database requires some application-level support (the other tabs need to be made aware of this somehow, and drift provides no mechanism to inform users that the database has been closed without them doing anything).

Ideally I should just figure out the corruption issue, making these workarounds unnecessary.

@miguelcmedeiros
Copy link
Author

We could expose the appropriate hooks to WasmDatabase.open() like onBlocked and onVersionChange as mentioned in https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB#version_changes_while_a_web_app_is_open_in_another_tab.

This way the tab triggering the database deletion (or database migration) gets notified in onBlocked that other database connection are blocking and the other tabs get notified in onVersionChange that something is happening that might require a page reload (or some other action like programatically reloading the page).

These 2 hooks are probably only relevant for the IndexedDB, but that can be made clear in the docs. Not sure how the in-memory or OPFS implementation handle database deletion/migration...

@miguelcmedeiros
Copy link
Author

Ideally I should just figure out the corruption issue, making these workarounds unnecessary.

If there's anything I can do to help, let me know, although I haven't figure out a way to reproduce this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants