options.proxyUri = callee.defaultProxyUri;
}
- const thePromise = new Promise(function(promiseResolve, promiseReject){
+ const thePromise = new Promise(function(promiseResolve, promiseReject_){
const loggers = {
0:console.error.bind(console),
1:console.warn.bind(console),
const sqlite3_vfs = capi.sqlite3_vfs;
const sqlite3_file = capi.sqlite3_file;
const sqlite3_io_methods = capi.sqlite3_io_methods;
- const W = new Worker(options.proxyUri);
- W._originalOnError = W.onerror /* will be restored later */;
- W.onerror = function(err){
- // The error object doesn't contain any useful info when the
- // failure is, e.g., that the remote script is 404.
- promiseReject(new Error("Loading OPFS async Worker failed for unknown reasons."));
- };
/**
Generic utilities for working with OPFS. This will get filled out
by the Promise setup and, on success, installed as sqlite3.opfs.
gets called at all in a wasm build, which is undefined).
*/
+ const promiseReject = function(err){
+ opfsVfs.dispose();
+ return promiseReject_(err);
+ };
+ const W = new Worker(options.proxyUri);
+ W._originalOnError = W.onerror /* will be restored later */;
+ W.onerror = function(err){
+ // The error object doesn't contain any useful info when the
+ // failure is, e.g., that the remote script is 404.
+ promiseReject(new Error("Loading OPFS async Worker failed for unknown reasons."));
+ };
+
/**
State which we send to the async-api Worker or share with it.
This object must initially contain only cloneable or sharable
require a bit of acrobatics but should be feasible.
*/
const state = Object.create(null);
- state.littleEndian = true;
state.verbose = options.verbose;
+ state.littleEndian = true;
+ /** If true, the async counterpart should log exceptions to
+ the serialization channel. That produces a great deal of
+ noise for seemingly innocuous things like xAccess() checks
+ for missing files. */
+ state.asyncS11nExceptions = false;
/* Size of file I/O buffer block. 64k = max sqlite3 page size. */
state.fileBufferSize =
1024 * 64;
state.sabS11nOffset = state.fileBufferSize;
/**
The size of the block in our SAB for serializing arguments and
- result values. Need to be large enough to hold serialized
+ result values. Needs to be large enough to hold serialized
values of any of the proxied APIs. Filenames are the largest
part but are limited to opfsVfs.$mxPathname bytes.
*/
counterpart...
*/
state.sq3Codes = Object.create(null);
- state.sq3Codes._reverse = Object.create(null);
[
'SQLITE_ERROR', 'SQLITE_IOERR',
'SQLITE_NOTFOUND', 'SQLITE_MISUSE',
'SQLITE_OPEN_READONLY'
].forEach(function(k){
state.sq3Codes[k] = capi[k] || toss("Maintenance required: not found:",k);
- state.sq3Codes._reverse[capi[k]] = k;
});
- const isWorkerErrCode = (n)=>!!state.sq3Codes._reverse[n];
-
/**
Runs the given operation (by name) in the async worker
counterpart, waits for its response, and returns the result
const t = performance.now();
Atomics.wait(state.sabOPView, state.opIds.rc, -1);
const rc = Atomics.load(state.sabOPView, state.opIds.rc);
- if(rc){
+ metrics[op].wait += performance.now() - t;
+ if(rc && state.asyncS11nExceptions){
const err = state.s11n.deserialize();
if(err) error(op+"() async error:",...err);
}
- metrics[op].wait += performance.now() - t;
return rc;
};
xFileSize: function(pFile,pSz64){
mTimeStart('xFileSize');
const rc = opRun('xFileSize', pFile);
- if(!isWorkerErrCode(rc)){
+ if(0==rc){
const sz = state.s11n.deserialize()[0];
wasm.setMemValue(pSz64, BigInt(sz), 'i64');
}
const dbFile = "/sanity/check/file"+randomFilename(8);
const zDbFile = wasm.scopedAllocCString(dbFile);
let rc;
+ state.s11n.serialize("This is ä string.");
+ rc = state.s11n.deserialize();
+ log("deserialize() says:",rc);
+ if("This is ä string."!==rc[0]) toss("String d13n error.");
vfsSyncWrappers.xAccess(opfsVfs.pointer, zDbFile, 0, pOut);
rc = wasm.getMemValue(pOut,'i32');
log("xAccess(",dbFile,") exists ?=",rc);
fid, openFlags, pOut);
log("open rc =",rc,"state.sabOPView[xOpen] =",
state.sabOPView[state.opIds.xOpen]);
- if(isWorkerErrCode(rc)){
+ if(0!==rc){
error("open failed with code",rc);
return;
}
//log("Worker.onmessage:",data);
switch(data.type){
case 'opfs-async-loaded':
- /*Pass our config and shared state on to the async worker.*/
+ /*Arrives as soon as the asyc proxy finishes loading.
+ Pass our config and shared state on to the async worker.*/
W.postMessage({type: 'opfs-async-init',args: state});
break;
case 'opfs-async-inited':{
- /*Indicates that the async partner has received the 'init',
- so we now know that the state object is no longer subject to
- being copied by a pending postMessage() call.*/
+ /*Indicates that the async partner has received the 'init'
+ and has finished initializing, so the real work can
+ begin...*/
try {
const rc = capi.sqlite3_vfs_register(opfsVfs.pointer, 0);
if(rc){
- opfsVfs.dispose();
toss("sqlite3_vfs_register(OPFS) failed with rc",rc);
}
if(opfsVfs.pointer !== capi.sqlite3_vfs_find("opfs")){
try {
await getDirForPath(dirname+"/filepart", true);
}catch(e){
- state.s11n.serialize(e.message);
+ state.s11n.storeException(e);
rc = state.sq3Codes.SQLITE_IOERR;
}finally{
wTimeEnd();
const [dh, fn] = await getDirForPath(filename);
await dh.getFileHandle(fn);
}catch(e){
- state.s11n.serialize(e.message);
+ state.s11n.storeException(e);
rc = state.sq3Codes.SQLITE_IOERR;
}finally{
wTimeEnd();
filename = filename.join('/');
}
}catch(e){
- state.s11n.serialize(e.message);
+ state.s11n.storeException(e);
rc = state.sq3Codes.SQLITE_IOERR_DELETE;
}
wTimeEnd();
state.s11n.serialize(Number(sz));
sz = 0;
}catch(e){
- state.s11n.serialize(e.message);
+ state.s11n.storeException(e);
sz = state.sq3Codes.SQLITE_IOERR;
}
wTimeEnd();
}catch(e){
wTimeEnd();
error(opName,e);
- state.s11n.serialize(e.message);
+ state.s11n.storeException(e);
storeAndNotify(opName, state.sq3Codes.SQLITE_IOERR);
}
mTimeEnd();
}
}catch(e){
error("xRead() failed",e,fh);
- state.s11n.serialize(e.message);
+ state.s11n.storeException(e);
rc = state.sq3Codes.SQLITE_IOERR_READ;
}
storeAndNotify('xRead',rc);
wTimeStart('xSync');
await fh.accessHandle.flush();
}catch(e){
- state.s11n.serialize(e.message);
+ state.s11n.storeException(e);
}finally{
wTimeEnd();
}
await fh.accessHandle.truncate(size);
}catch(e){
error("xTruncate():",e,fh);
- state.s11n.serialize(e.message);
+ state.s11n.storeException(e);
rc = state.sq3Codes.SQLITE_IOERR_TRUNCATE;
}
wTimeEnd();
) ? 0 : state.sq3Codes.SQLITE_IOERR_WRITE;
}catch(e){
error("xWrite():",e,fh);
- state.s11n.serialize(e.message);
+ state.s11n.storeException(e);
rc = state.sq3Codes.SQLITE_IOERR_WRITE;
}finally{
wTimeEnd();
}
metrics.s11n.serialize.time += performance.now() - t;
};
+
+ state.s11n.storeException = state.asyncS11nExceptions
+ ? ((e)=>state.s11n.serialize(e.message))
+ : ()=>{};
+
return state.s11n;
}/*initS11n()*/;
/* Receive shared state from synchronous partner */
const opt = data.args;
state.littleEndian = opt.littleEndian;
+ state.asyncS11nExceptions = opt.asyncS11nExceptions;
state.verbose = opt.verbose ?? 2;
state.fileBufferSize = opt.fileBufferSize;
state.sabS11nOffset = opt.sabS11nOffset;
-C Doc\scleanups\sand\sadditions.\sAdd\sa\sway\sfor\sthe\sOPFS\sasync\srunner\sto\spropagate\sexception\stext\sto\sthe\scalling\sthread.
-D 2022-09-21T12:27:35.940
+C Correct\smistyped\s--shrink-memory\sflag\sin\sspeedtest1-worker.\sMinor\sOPFS\sproxy\scleanups.
+D 2022-09-21T14:02:47.634
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F ext/wasm/api/sqlite3-api-cleanup.js 8564a6077cdcaea9a9f428a019af8a05887f0131e6a2a1e72a7ff1145fadfe77
F ext/wasm/api/sqlite3-api-glue.js 366d580c8e5bf7fcf4c6dee6f646c31f5549bd417ea03a59a0acca00e8ecce30
F ext/wasm/api/sqlite3-api-oo1.js f974e79d9af8f26bf33928c5730b0988cc706d14f59a5fe36394739b92249841
-F ext/wasm/api/sqlite3-api-opfs.js dbbce38b0cd89d1eaf829546e2999241127150a40ff2e0331d842a1f31c756e5
+F ext/wasm/api/sqlite3-api-opfs.js d623ea3519cd81fe18e243adfdd07cd1fa4b07ff3b0fd0d2b269beb0e127acb3
F ext/wasm/api/sqlite3-api-prologue.js 6f3a67c4db37e884d33a05e5cf6d9d9bc012226a18c09f33f662fefd99840a63
F ext/wasm/api/sqlite3-api-worker1.js 2eeb2a24e1a90322d84a9b88a99919b806623de62792436446099c0988f2030b
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
F ext/wasm/scratchpad-wasmfs-main.html 20cf6f1a8f368e70d01e8c17200e3eaa90f1c8e1029186d836d14b83845fbe06
F ext/wasm/scratchpad-wasmfs-main.js f0836e3576df7a89390d777bb53e142e559e8a79becfb2a5a976490b05a1c4fa
F ext/wasm/speedtest1-wasmfs.html 9d8cd19eab8854d17f7129aa11607cae6f6d9857c505a4aef13000588583d93e
-F ext/wasm/speedtest1-worker.html ede59f2c1884bf72e3d650064604b48703c81848250b19b8063d260aa3a2201d
+F ext/wasm/speedtest1-worker.html 802cbd09a14b5a7abb4b66bff243d5fd89fd476ffe083554bdfd4c177fb6474c
F ext/wasm/speedtest1-worker.js 11e7f68cedd2a83b0e638f94c1d2f58406ba672a7e88b66bff5d4f4284e8ba16
F ext/wasm/speedtest1.html 8ae6ece128151d01f90579de69cfa06f021acdb760735250ef745eba7ed05d49
F ext/wasm/split-speedtest1-script.sh a3e271938d4d14ee49105eb05567c6a69ba4c1f1293583ad5af0cd3a3779e205 x
F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d82675bd63d9c2d97a15f0
F ext/wasm/sql/001-sudoku.sql 35b7cb7239ba5d5f193bc05ec379bcf66891bce6f2a5b3879f2f78d0917299b5
-F ext/wasm/sqlite3-opfs-async-proxy.js 0523e3093df2ad2c58691aa65c5e32c0aafb1bbabb6119dd9406d34a8e16dd68
+F ext/wasm/sqlite3-opfs-async-proxy.js 483b6326e268589ed3749a4d1a60b4ec2afa8ff7c218a09d39430e3bde89862e
F ext/wasm/sqlite3-worker1-promiser.js 4fd0465688a28a75f1d4ee4406540ba494f49844e3cad0670d0437a001943365
F ext/wasm/sqlite3-worker1.js 0c1e7626304543969c3846573e080c082bf43bcaa47e87d416458af84f340a9e
F ext/wasm/test-opfs-vfs.html eb69dda21eb414b8f5e3f7c1cc0f774103cc9c0f87b2d28a33419e778abfbab5
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 777077c4c2249e1ec78390d4f65aaf281c1fbefcef4bcc7609199e995645ceb6
-R 52ae18958684abb42f4ad80857c37c9c
+P 5c5e80652825cf883e6c17809cb98f2bf17d5feac2d263f6f492479154730dab
+R 47f6cfb5732f21f9dd8243259a29763d
U stephan
-Z 4853fab0e74bf411129cdad2e17be435
+Z efa6548d913df45daccab7f9511bade7
# Remove this line to create a well-formed Fossil manifest.