isar / isar/hive

deleteFromDisk-Call is blocked in Web because of open DB connections

Open
#1,193 1 comment 3 reactions 0 assignees View on GitHub
problem
Dominant language
Dart
Stars
4.4k
Forks
449
PR merge metrics
No merged PRs in 30d

Description

The call to `await box.deleteFromDisk();` blocks endlessly on the web due to an open DB connection. The iOS platform does not have this problem.

Hive uses IndexedDB as implementation for the Web-Plattform. The problem lies in line 212 of the file storage_backend_js.dart. Here deleteDatabase is called and awaited.
```
// directly deleting the entire DB if a non-collection Box
if (_db.objectStoreNames?.length == 1) {
await indexDB!.deleteDatabase(_db.name!);
} else {
```

If you look at the [w3c standard documentation](https://w3c.github.io/IndexedDB/#dom-idbopendbrequest-onblocked) of the deleteDatabase method, you will see that the call blocks on open database connections until all database connections are closed. A version change event is fired for this.

The [Dart implementation ](https://api.dart.dev/stable/2.19.6/dart-indexed_db/IdbFactory/deleteDatabase.html) of the deleteDatabase method shows the possibility to register an onBlocked event listener.

If this is done, an IDBVersionChangeEvent appears in the log, confirming the assumption.
` await (indexDB! as IdbFactory).deleteDatabase(_db.name!, onBlocked: (event) { print(event);});`

For Web, the problem can be solved by calling the method close beforehand. In the mobile environment however then the following error occurs.
`FileSystemException: File closed, path = '/data/user/0/de.hschaeufler.app/app_flutter/cache_box.hive'`

This is a deviation between the web and mobile implementation of Hive. Considering the IndexedDB standard, open database connections during deletion, should be taken into account possibly directly when creating the database connection.

[w3c IndexedDB upgradeneeded Event](https://w3c.github.io/IndexedDB/#eventdef-idbopendbrequest-upgradeneeded )
> An event with type versionchange will be fired at an open connection if an attempt is made to upgrade or delete the database. This gives the connection the opportunity to close to allow the upgrade or delete to proceed.

[w3c Handling Versionchange - Example 2](https://w3c.github.io/IndexedDB/#handling-versionchange)
> Another way is to call the connection's close() method. However, you need to make sure your app is aware of this, as subsequent attempts to access the database will fail.
>
> db.onversionchange = function() {
> saveUnsavedData().then(function() {
> db.close();
> stopUsingTheDatabase();
> });
> };
>
> function stopUsingTheDatabase() {
> // Put the app into a state where it no longer uses the database.
> }
>

**Version**
- Platform: Web, iOS
- Flutter version: 3.7.5
- Hive version: 2.2.3

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in storage_backend_js.dart around line 212, where deleteFromDisk awaits deleteDatabase, and review the web database connection lifecycle. Compare the proposed close behavior with the mobile implementation and verify that deleteFromDisk completes on the web without causing the reported mobile FileSystemException.

Written by the indexing model from the issue text.

Assessment

Tech stack
dart, flutter
Domain
database
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.