Add an option to the opfs-sahpool VFS which tells it to ignore a previous init failure and retry, as an opt-in workaround for a browser quirk which occasionally denies OPFS access on the first attempt and permits it on subsequent attempts. This resolves [https://github.com/sqlite/sqlite-wasm/issues/79|issue #79 of the npm distribution].
FossilOrigin-Name: fbf3948a4ba27c6ebf55b24e7463b20026439f04d1974bafe78df5c5bc958f59
This commit is contained in:
@@ -102,7 +102,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
clearOnInit: false,
|
||||
/* Logging verbosity 3+ == everything, 2 == warnings+errors, 1 ==
|
||||
errors only. */
|
||||
verbosity: 2
|
||||
verbosity: 2,
|
||||
forceReinitIfPreviouslyFailed: false
|
||||
});
|
||||
|
||||
/** Logging routines, from most to least serious. */
|
||||
@@ -1004,9 +1005,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
return true;
|
||||
};
|
||||
|
||||
/** Only for testing a rejection case. */
|
||||
let instanceCounter = 0;
|
||||
|
||||
/**
|
||||
installOpfsSAHPoolVfs() asynchronously initializes the OPFS
|
||||
SyncAccessHandle (a.k.a. SAH) Pool VFS. It returns a Promise which
|
||||
@@ -1081,12 +1079,26 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
the default directory. If no directory is explicitly provided
|
||||
then a directory name is synthesized from the `name` option.
|
||||
|
||||
Peculiarities of this VFS:
|
||||
|
||||
- `forceReinitIfPreviouslyFailed`: (default=`false`) Is a fallback option
|
||||
to assist in working around certain flaky environments which may
|
||||
mysteriously fail to permit access to OPFS sync access handles on
|
||||
an initial attempt but permit it on a second attemp. This option
|
||||
should never be used but is provided for those who choose to
|
||||
throw caution to the wind and trust such environments. If this
|
||||
option is truthy _and_ the previous attempt to initialize this
|
||||
VFS with the same `name` failed, the VFS will attempt to
|
||||
initialize a second time instead of returning the cached
|
||||
failure. See discussion at:
|
||||
<https://github.com/sqlite/sqlite-wasm/issues/79>
|
||||
|
||||
|
||||
Peculiarities of this VFS vis a vis other SQLite VFSes:
|
||||
|
||||
- Paths given to it _must_ be absolute. Relative paths will not
|
||||
be properly recognized. This is arguably a bug but correcting it
|
||||
requires some hoop-jumping in routines which have no business
|
||||
doing tricks.
|
||||
doing such tricks.
|
||||
|
||||
- It is possible to install multiple instances under different
|
||||
names, each sandboxed from one another inside their own private
|
||||
@@ -1207,13 +1219,25 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
handles are currently in use, e.g. by an sqlite3 db.
|
||||
*/
|
||||
sqlite3.installOpfsSAHPoolVfs = async function(options=Object.create(null)){
|
||||
const vfsName = options.name || optionDefaults.name;
|
||||
if(0 && 2===++instanceCounter){
|
||||
throw new Error("Just testing rejection.");
|
||||
options = Object.assign(Object.create(null), optionDefaults, (options||{}));
|
||||
const vfsName = options.name;
|
||||
if(options.$testThrowPhase1){
|
||||
throw options.$testThrowPhase1;
|
||||
}
|
||||
if(initPromises[vfsName]){
|
||||
//console.warn("Returning same OpfsSAHPool result",options,vfsName,initPromises[vfsName]);
|
||||
return initPromises[vfsName];
|
||||
try {
|
||||
const p = await initPromises[vfsName];
|
||||
//log("installOpfsSAHPoolVfs() returning cached result",options,vfsName,p);
|
||||
return p;
|
||||
}catch(e){
|
||||
//log("installOpfsSAHPoolVfs() got cached failure",options,vfsName,e);
|
||||
if( options.forceReinitIfPreviouslyFailed ){
|
||||
delete initPromises[vfsName];
|
||||
/* Fall through and try again. */
|
||||
}else{
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!globalThis.FileSystemHandle ||
|
||||
!globalThis.FileSystemDirectoryHandle ||
|
||||
@@ -1238,8 +1262,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
ensues.
|
||||
*/
|
||||
return initPromises[vfsName] = apiVersionCheck().then(async function(){
|
||||
if(options.$testThrowInInit){
|
||||
throw options.$testThrowInInit;
|
||||
if(options.$testThrowPhase2){
|
||||
throw options.$testThrowPhase2;
|
||||
}
|
||||
const thePool = new OpfsSAHPool(options);
|
||||
return thePool.isReady.then(async()=>{
|
||||
@@ -1255,7 +1279,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
oo1.DB.dbCtorHelper.call(this, opt);
|
||||
};
|
||||
OpfsSAHPoolDb.prototype = Object.create(oo1.DB.prototype);
|
||||
// yes or no? OpfsSAHPoolDb.PoolUtil = poolUtil;
|
||||
poolUtil.OpfsSAHPoolDb = OpfsSAHPoolDb;
|
||||
oo1.DB.dbCtorHelper.setVfsPostOpenSql(
|
||||
theVfs.pointer,
|
||||
|
||||
@@ -2824,7 +2824,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
name: 'Session API sanity checks',
|
||||
predicate: ()=>!!capi.sqlite3changegroup_add,
|
||||
test: function(sqlite3){
|
||||
warn("The session API tests could use some expansion.");
|
||||
//warn("The session API tests could use some expansion.");
|
||||
const db1 = new sqlite3.oo1.DB(), db2 = new sqlite3.oo1.DB();
|
||||
const sqlInit = [
|
||||
"create table t(rowid INTEGER PRIMARY KEY,a,b); ",
|
||||
@@ -2859,7 +2859,9 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
.assert('b4' === db1.selectValue('select b from t where rowid=4'))
|
||||
.assert(3 === db1.selectValue('select count(*) from t'));
|
||||
|
||||
const testSessionEnable = false;
|
||||
const testSessionEnable =
|
||||
false /* it's not yet clear whether these test failures are
|
||||
broken tests or broken bindings. */;
|
||||
if(testSessionEnable){
|
||||
rc = capi.sqlite3session_enable(pSession, 0);
|
||||
T.assert( 0 === rc )
|
||||
@@ -2870,7 +2872,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
.assert( capi.sqlite3session_enable(pSession, -1) > 0 )
|
||||
.assert(undefined === db1.selectValue('select a from t where rowid=2'));
|
||||
}else{
|
||||
warn("sqlite3session_enable() tests are currently disabled.");
|
||||
//warn("sqlite3session_enable() tests are currently disabled.");
|
||||
}
|
||||
let db1Count = db1.selectValue("select count(*) from t");
|
||||
T.assert( db1Count === (testSessionEnable ? 2 : 3) );
|
||||
@@ -3177,13 +3179,28 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
.assert(!sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name));
|
||||
|
||||
let cErr, u3;
|
||||
conf2.$testThrowInInit = new Error("Testing throwing during init.");
|
||||
conf2.$testThrowPhase2 = new Error("Testing throwing during init.");
|
||||
conf2.name = sahPoolConfig.name+'-err';
|
||||
const P3 = await inst(conf2).then(u=>u3 = u).catch((e)=>cErr=e);
|
||||
T.assert(P3 === conf2.$testThrowInInit)
|
||||
T.assert(P3 === conf2.$testThrowPhase2)
|
||||
.assert(cErr === P3)
|
||||
.assert(undefined === u3)
|
||||
.assert(!sqlite3.capi.sqlite3_vfs_find(conf2.name));
|
||||
delete conf2.$testThrowPhase2;
|
||||
T.assert(cErr === await inst(conf2).catch(e=>e),
|
||||
"Init result is cached even if it failed");
|
||||
|
||||
/* Ensure that the forceReinitIfPreviouslyFailed fallback bypasses
|
||||
the VFS init cache... */
|
||||
cErr = u3 = undefined;
|
||||
conf2.forceReinitIfPreviouslyFailed = true;
|
||||
conf2.verbosity = 3;
|
||||
const P3b = await inst(conf2).then(u=>u3 = u).catch((e)=>cErr=e);
|
||||
T.assert(undefined === cErr)
|
||||
.assert(P3b === u3)
|
||||
.assert(P3b === await inst(conf2))
|
||||
.assert(true === await u3.removeVfs())
|
||||
.assert(false === await P3b.removeVfs());
|
||||
}
|
||||
}/*OPFS SAH Pool sanity checks*/)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
C sqldiff:\sfail\sif\sthe\s2nd\sdb\sargument\scannot\sbe\sopened\sread-only.
|
||||
D 2024-07-12T14:41:16.904
|
||||
C Add\san\soption\sto\sthe\sopfs-sahpool\sVFS\swhich\stells\sit\sto\signore\sa\sprevious\sinit\sfailure\sand\sretry,\sas\san\sopt-in\sworkaround\sfor\sa\sbrowser\squirk\swhich\soccasionally\sdenies\sOPFS\saccess\son\sthe\sfirst\sattempt\sand\spermits\sit\son\ssubsequent\sattempts.\sThis\sresolves\s[https://github.com/sqlite/sqlite-wasm/issues/79|issue\s#79\sof\sthe\snpm\sdistribution].
|
||||
D 2024-07-13T01:02:57.267
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@@ -618,7 +618,7 @@ F ext/wasm/api/sqlite3-api-worker1.c-pp.js 5cc22a3c0d52828cb32aad8691488719f47d2
|
||||
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
|
||||
F ext/wasm/api/sqlite3-opfs-async-proxy.js e8f1df56e97a29004a95a2eddd26778f52c33b3e797d32d4b1b668a38e6493dd
|
||||
F ext/wasm/api/sqlite3-vfs-helper.c-pp.js 3f828cc66758acb40e9c5b4dcfd87fd478a14c8fb7f0630264e6c7fa0e57515d
|
||||
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 8433ee332d5f5e39fb19427fccb7bad7f44aa99b5504daad3343fc128c311e78
|
||||
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 8c59ff35224adbe926b85d0c6debedc63c3c949d4cee761b3a74867b56155341
|
||||
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 258a0d7c2a952ee360c13d7e4551b11d3f4fbe6dec1df6162866eca4d54e8443
|
||||
F ext/wasm/api/sqlite3-vtab-helper.c-pp.js a2fcbc3fecdd0eea229283584ebc122f29d98194083675dbe5cb2cf3a17fe309
|
||||
F ext/wasm/api/sqlite3-wasm.c 9267174b9b0591b4f71193542ab57adf95bb9415f7d3453acf4a8ca8052f5e6c
|
||||
@@ -667,7 +667,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
|
||||
F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c
|
||||
F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c
|
||||
F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2
|
||||
F ext/wasm/tester1.c-pp.js 6d0a9aa44a97b4aadd582e0999ce45a2671b854a12ea3205d1c908da6bd4bdef
|
||||
F ext/wasm/tester1.c-pp.js 74ade5f0d61db790b4e403f6bf7c0d346e19ec876cdee109c22ae4214aa89f4e
|
||||
F ext/wasm/tests/opfs/concurrency/index.html 0802373d57034d51835ff6041cda438c7a982deea6079efd98098d3e42fbcbc1
|
||||
F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d
|
||||
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
|
||||
@@ -2195,8 +2195,9 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P af41a1e6fc8b36e9bf65a5bb0154e1ce7eb99903cb5a3e4779322527c29d8780
|
||||
R cd90730c86cb7f967c489fb04ff854ed
|
||||
P e8b33525fc2b4d609a7be9acc43fbc66638effaa7b092b48568ded6c53c4f4db c9f0a6090258534a3d81066df5610229183a8457fc60d5034b4b94d9a29796e4
|
||||
R 674df08c7c71be5b7a456e9edf4c5bff
|
||||
T +closed c9f0a6090258534a3d81066df5610229183a8457fc60d5034b4b94d9a29796e4 Closed\sby\sintegrate-merge.
|
||||
U stephan
|
||||
Z 00ecf88c93499ce80acd271f6ea6acd0
|
||||
Z 46da404de8b55901677e43a878b084be
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
e8b33525fc2b4d609a7be9acc43fbc66638effaa7b092b48568ded6c53c4f4db
|
||||
fbf3948a4ba27c6ebf55b24e7463b20026439f04d1974bafe78df5c5bc958f59
|
||||
|
||||
Reference in New Issue
Block a user