Skip to content

IDB VFSs: add getIDBFactory and prefix options - #387

Open
lalexdotcom wants to merge 1 commit into
rhashimoto:masterfrom
lalexdotcom:idb-factory-prefix
Open

lalexdotcom wants to merge 1 commit into
rhashimoto:masterfrom
lalexdotcom:idb-factory-prefix

Conversation

@lalexdotcom

Copy link
Copy Markdown
Contributor

This is the follow-up offered in #380: the same options for IDBBatchAtomicVFS and IDBMirrorVFS, following that PR's API and test layout.

Why

Both VFSs open their database with the global indexedDB. A Storage Bucket has its own IDBFactory (bucket.indexedDB) and its own persistence and durability settings. So an app could keep the databases it can't afford to lose in a bucket opened with persisted: true, and leave the ones it can rebuild in the default bucket, where the browser may evict them.

The change

  • getIDBFactory returns the IDBFactory the VFS opens its database with. By default it returns indexedDB. It may return the factory itself or a promise of one.
  • prefix goes in front of the Web Lock and BroadcastChannel names the VFS derives from its file names, as in OPFS VFSs: add getRoot and lockPrefix options #380. By default it is empty, so nothing changes.
  • Both are read from this.options, which holds the defaults. IDBMirrorVFS now has an options field and stops ignoring its options argument. IDBBatchAtomicVFS keeps idbName.

IDBBatchAtomicVFS gets its locks from WebLocksMixin, so prefix is an option of the mixin, next to lockPolicy and lockTimeout. That is why this PR changes two VFSs at once, and also why the option applies to the other VFSs that use the mixin: OPFSAdaptiveVFS, OPFSAnyContextVFS and OPFSPermutedVFS. If you'd rather keep it to the IndexedDB VFSs, I can change that.

In IDBMirrorVFS the prefix is also taken into account where #getOldestTxInUse() reads the transaction locks back.

The tests

test/vfs_idb_factory.js runs for both VFSs, on the model of vfs_root.js. A connection whose getIDBFactory returns a Storage Bucket's factory must:

  • keep its database in that bucket and not in the default one;
  • keep apart from a database of the same name in the default factory, in its data and in the messages it receives;
  • not wait for a write transaction on a file of the same name in the default factory.

A getIDBFactory that rejects must make the open fail with its error. New -customFactory configurations also run vfs_xAccess, vfs_xOpen, vfs_xClose, vfs_xRead and vfs_xWrite through a bucket, and the bucket is deleted on reset.

Storage Buckets exist only in Chromium. Elsewhere, the bucket tests are pending and only the rejection test runs. On master, all four tests fail in Chrome for both VFSs. With the prefix emptied and the factory used, the lock test still fails for both VFSs, and the separation test also fails for IDBMirrorVFS, whose channels would otherwise be shared.

Conflicts with my other open PRs

#385 adds an import to test/IDBMirrorVFS.test.js at the same place as this PR. That is the only conflict.

This PR doesn't conflict with #381, #382, #384 or #386.

Checklist

  • I grant to recipients of this Project distribution a perpetual,
    non-exclusive, royalty-free, irrevocable copyright license to reproduce, prepare
    derivative works of, publicly display, sublicense, and distribute this
    Contribution and such derivative works.
  • I certify that I am legally entitled to grant this license, and that this
    Contribution contains no content requiring a license from any third party.

@lalexdotcom

Copy link
Copy Markdown
Contributor Author

One more note on #getOldestTxInUse(): no test covers the prefixed comparison there. With it reverted to m[1] === file.path, IDBMirrorVFS.test.js still passes. As far as I can tell, no test checks that function's result even without a prefix. It only matters when a connection that missed a broadcast catches up from the tx store. A wrong oldest id would delete records that connection still needs, and it could no longer catch up.

If you'd like, I can add an IDBMirrorVFS test for it. One connection keeps an old view open in a read transaction while another commits twice, and the test checks that the tx store still holds the transactions after the old view. It would cover the unprefixed case too.

The same options rhashimoto#380 gave the OPFS VFSs. getIDBFactory lets an app keep
a database in another IDBFactory than the global one, such as the
indexedDB of a Storage Bucket, which has its own persistence and
durability settings. prefix keeps the Web Lock and BroadcastChannel names
of a file apart from those of a file of the same name in another factory.

The lock names of IDBBatchAtomicVFS are built by WebLocksMixin, so the
prefix option lives there and also applies to the other VFSs that use the
mixin: OPFSAdaptiveVFS, OPFSAnyContextVFS and OPFSPermutedVFS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@lalexdotcom

Copy link
Copy Markdown
Contributor Author

Rebased onto master (#384 and #385). The only conflict was the imports at the top of test/IDBMirrorVFS.test.js, where #385 added vfs_close_settles; both are kept. The rest of the change is unchanged, and the suite passes on Chrome.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant