From c259defab56ca5c81bb7a1425ec6cfcdbab3cdbb Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Mon, 10 Jun 2024 15:30:14 -0400 Subject: [PATCH] Move database.get and database.set off the main thread. --- core/core.js | 67 ++- run.log | 1062 --------------------------------------------- src/database.js.c | 169 ++++++-- src/tests.c | 49 ++- 4 files changed, 194 insertions(+), 1153 deletions(-) delete mode 100644 run.log diff --git a/core/core.js b/core/core.js index f1a583d5..5efb472d 100644 --- a/core/core.js +++ b/core/core.js @@ -206,7 +206,7 @@ function getUser(caller, process) { * @param {*} process * @returns */ -function getApps(user, process) { +async function getApps(user, process) { if ( process.credentials && process.credentials.session && @@ -221,10 +221,12 @@ function getApps(user, process) { if (user) { let db = new Database(user); try { - let names = JSON.parse(db.get('apps')); - return Object.fromEntries( - names.map((name) => [name, db.get('path:' + name)]) - ); + let names = JSON.parse(await db.get('apps')); + let result = {}; + for (let name of names) { + result[name] = await db.get('path:' + name); + } + return result; } catch {} } return {}; @@ -320,9 +322,9 @@ async function getProcessBlob(blobId, key, options) { } }, user: getUser(process, process), - users: function () { + users: async function () { try { - return JSON.parse(new Database('auth').get('users')); + return JSON.parse(await new Database('auth').get('users')); } catch { return []; } @@ -509,25 +511,20 @@ async function getProcessBlob(blobId, key, options) { setGlobalSettings(gGlobalSettings); print('Done.'); }; - imports.core.deleteUser = function (user) { - return Promise.resolve( - imports.core.permissionTest('delete_user') - ).then(function () { - let db = new Database('auth'); - - db.remove('user:' + user); - - let users = new Set(); - let users_original = db.get('users'); - try { - users = new Set(JSON.parse(users_original)); - } catch {} - users.delete(user); - users = JSON.stringify([...users].sort()); - if (users !== users_original) { - db.set('users', users); - } - }); + imports.core.deleteUser = async function (user) { + await imports.core.permissionTest('delete_user') + let db = new Database('auth'); + db.remove('user:' + user); + let users = new Set(); + let users_original = await db.get('users'); + try { + users = new Set(JSON.parse(users_original)); + } catch {} + users.delete(user); + users = JSON.stringify([...users].sort()); + if (users !== users_original) { + await db.set('users', users); + } }; } if (options.api) { @@ -806,10 +803,10 @@ async function getProcessBlob(blobId, key, options) { * @param {*} settings * @returns */ -function setGlobalSettings(settings) { +async function setGlobalSettings(settings) { gGlobalSettings = settings; try { - return new Database('core').set('settings', JSON.stringify(settings)); + return await new Database('core').set('settings', JSON.stringify(settings)); } catch (error) { print('Error storing settings:', error); } @@ -1052,7 +1049,7 @@ async function blobHandler(request, response, blobId, uri) { let database = new Database(user); let app_object = JSON.parse(utf8Decode(request.body)); - let previous_id = database.get('path:' + appName); + let previous_id = await database.get('path:' + appName); if (previous_id) { try { let previous_object = JSON.parse( @@ -1073,7 +1070,7 @@ async function blobHandler(request, response, blobId, uri) { let newBlobId = await ssb.blobStore(JSON.stringify(app_object)); let apps = new Set(); - let apps_original = database.get('apps'); + let apps_original = await database.get('apps'); try { apps = new Set(JSON.parse(apps_original)); } catch {} @@ -1082,9 +1079,9 @@ async function blobHandler(request, response, blobId, uri) { } apps = JSON.stringify([...apps].sort()); if (apps != apps_original) { - database.set('apps', apps); + await database.set('apps', apps); } - database.set('path:' + appName, newBlobId); + await database.set('path:' + appName, newBlobId); response.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'}); response.end('/' + newBlobId); } else { @@ -1115,10 +1112,10 @@ async function blobHandler(request, response, blobId, uri) { let database = new Database(user); let apps = new Set(); try { - apps = new Set(JSON.parse(database.get('apps'))); + apps = new Set(JSON.parse(await database.get('apps'))); } catch {} if (apps.delete(appName)) { - database.set('apps', JSON.stringify([...apps].sort())); + await database.set('apps', JSON.stringify([...apps].sort())); } database.remove('path:' + appName); } else { @@ -1230,7 +1227,7 @@ ssb.addEventListener('connections', function () { async function loadSettings() { let data = {}; try { - let settings = new Database('core').get('settings'); + let settings = await new Database('core').get('settings'); if (settings) { data = JSON.parse(settings); } diff --git a/run.log b/run.log deleted file mode 100644 index a57fce61..00000000 --- a/run.log +++ /dev/null @@ -1,1062 +0,0 @@ -File not foundHello, world! -Hello, world! -Hello, world! -Hello, world! -Hello, world! -exepath is /home/cory/src/tildefriends/out/debug/tildefriends -== running test bip39 == -1: body hair useful camp warm into cause riot two bamboo kick educate dinosaur advice seed type crisp where guilt avocado output rely lunch goddess -[pass] bip39 -== running test http == -Starting http. -curl returned 0 -curl returned 0 -size = 11 body=hello world -curl returned 0 -curl returned 0 -Done running. -[pass] http -== running test ssb == -Testing SSB. -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -ID @3bV0UxKK/AFwbDSw3Cfx3eXgjL6gNXy5HSwty0sLFFU=.ed25519 and @0jpl9/v9YIG3yjHF+XFM5M/iYCAMfB2TLmK7x0nZE0A=.ed25519 -blob stored &hgjLeSZeURdqZmq/k+zyqiIUr5RMU2ztJbzUcSHuUHQ=.sha256 12 => 1 -Waiting for connection. -callback1 change=0 connection=0x7c20e31c4808 -conns = 0 0 0 -callback0 change=0 connection=0x7c20e27a1808 -conns = 0 0 0 -callback0 change=1 connection=0x7c20e27a1808 -conns = 1 0 0 -callback0 change=3 connection=0x7c20e27a1808 -conns = 1 0 0 -callback1 change=1 connection=0x7c20e31c4808 -conns = 1 1 0 -callback1 change=3 connection=0x7c20e31c4808 -conns = 1 1 0 -callback1 change=3 connection=0x7c20e31c4808 -conns = 1 1 0 -callback1 change=3 connection=0x7c20e31c4808 -conns = 1 1 0 -Stopped broadcasts. -Waiting for messages. -callback1 change=3 connection=0x7c20e31c4808 -conns = 1 1 0 -callback0 change=3 connection=0x7c20e27a1808 -conns = 1 1 0 -callback0 change=3 connection=0x7c20e27a1808 -conns = 1 1 0 -callback0 change=3 connection=0x7c20e27a1808 -conns = 1 1 0 -callback1 change=3 connection=0x7c20e31c4808 -conns = 1 1 0 -callback1 change=3 connection=0x7c20e31c4808 -conns = 1 1 0 -callback0 change=3 connection=0x7c20e27a1808 -conns = 1 1 0 -callback0 change=3 connection=0x7c20e27a1808 -conns = 1 1 0 -callback0 change=3 connection=0x7c20e27a1808 -conns = 1 1 0 -Waiting for blob. -callback1 change=3 connection=0x7c20e31c4808 -conns = 1 1 0 -callback0 change=3 connection=0x7c20e27a1808 -conns = 1 1 0 -callback0 change=3 connection=0x7c20e27a1808 -conns = 1 1 0 -callback0 change=3 connection=0x7c20e27a1808 -conns = 1 1 0 -callback1 change=3 connection=0x7c20e31c4808 -conns = 1 1 0 -s1 = 12 sl = 12 -Waiting for message to self. -Waiting for message from other. -done -Connection cli0 0x7c20e31c4808 is closing: crypto_secretbox_easy close message. -callback1 change=3 connection=0x7c20e31c4808 -conns = 1 0 0 -callback1 change=3 connection=0x7c20e31c4808 -conns = 1 0 0 -callback1 change=3 connection=0x7c20e31c4808 -conns = 1 0 0 -callback1 change=3 connection=0x7c20e31c4808 -conns = 1 0 0 -callback1 change=2 connection=0x7c20e31c4808 -conns = 1 0 0 -final run -Connection srv1 0x7c20e27a1808 is closing: end of file. -callback0 change=3 connection=0x7c20e27a1808 -conns = 0 0 0 -callback0 change=3 connection=0x7c20e27a1808 -conns = 0 0 0 -callback0 change=3 connection=0x7c20e27a1808 -conns = 0 0 0 -callback0 change=3 connection=0x7c20e27a1808 -conns = 0 0 0 -callback0 change=2 connection=0x7c20e27a1808 -conns = 0 0 0 -done -destroy 0 -tf_ssb_destroy -Waiting for closes. -Waiting for rpc. -Closing connections. -Closed. -uv loop closed. -closing ssb context -destroy 1 -tf_ssb_destroy -Waiting for closes. -Waiting for rpc. -Closing connections. -Closed. -uv loop closed. -closing ssb context -close -[pass] ssb -== running test ssb_id == -Testing id conversion. -[pass] ssb_id -== running test ssb_following == -Testing following. -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -tf_ssb_destroy -Waiting for closes. -Waiting for rpc. -Closing connections. -Closed. -uv loop closed. -closing ssb context -[pass] ssb_following -== running test nop == -out/debug/tildefriends run --db-path=:meexepath is /home/cory/src/tildefriends/out/debug/tildefriends -setting zip path to (null) -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -prepare failed: no such table: properties -prepare failed: no such table: properties -will delete more blobs in 30000 ms -Running script out/test.js -Task[0x626000000108:out/test.js]> hi -tf_ssb_destroy -Waiting for closes. -Waiting for rpc. -Closing connections. -Closed. -uv loop closed. -Goodbye. -_tf_run_task is done. Goodbye. -exepath is /home/cory/src/tildefriends/out/debug/tildefriends -setting zip path to (null) -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -prepare failed: no such table: properties -prepare failed: no such table: properties -will delete more blobs in 30000 ms -Running script out/test.js -ERROR: Error: oops - at (out/test.js:1) - -ERROR: Error: oops - at (out/test.js:1) - -Reported an error. -tf_ssb_destroy -Waiting for closes. -Waiting for rpc. -Closing connections. -Closed. -uv loop closed. -Goodbye. -_tf_run_task is done. Goodbye. -exepath is /home/cory/src/tildefriends/out/debug/tildefriends -Task[0x626000000108:]> Poking the sandbox. This should fail. -Poking sandbox. -Sandbox poked. -exepath is /home/cory/src/tildefriends/out/debug/tildefriends -setting zip path to (null) -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -prepare failed: no such table: properties -prepare failed: no such table: properties -will delete more blobs in 30000 ms -Running script out/test.js -Task[0x626000000108:out/test.js]> child exited 127 0 -tf_ssb_destroy -Waiting for closes. -Waiting for rpc. -Closing connections. -Closed. -uv loop closed. -Goodbye. -_tf_run_task is done. Goodbye. -exepath is /home/cory/src/tildefriends/out/debug/tildefriends -Task[0x626000000108:]> I am the child process. -exepath is /home/cory/src/tildefriends/out/debug/tildefriends -setting zip path to (null) -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -prepare failed: no such table: properties -prepare failed: no such table: properties -will delete more blobs in 30000 ms -Running script out/test.js -Task[0x626000000108:out/test.js]> child exited 0 0 -exepath is /home/cory/src/tildefriends/out/debug/tildefriends -setting zip path to (null) -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -prepare failed: no such table: properties -prepare failed: no such table: properties -will delete more blobs in 30000 ms -Running script out/test.js -exepath is /home/cory/src/tildefriends/out/debug/tildefriends -setting zip path to (null) -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -prepare failed: no such table: properties -prepare failed: no such table: properties -will delete more blobs in 30000 ms -Running script out/test.js -Task[0x626000000108:out/test.js]> Caught: -exepath is /home/cory/src/tildefriends/out/debug/tildefriends -setting zip path to (null) -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -prepare failed: no such table: properties -prepare failed: no such table: properties -will delete more blobs in 30000 ms -Running script out/test.js -Task[0x626000000108:out/test.js]> Caught: oops -Task[0x626000000108:out/test.js]> stack: at (child.js:4) - at Promise (native) - at add (child.js:5) - -exepath is /home/cory/src/tildefriends/out/debug/tildefriends -setting zip path to (null) -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -will delete more blobs in 30000 ms -Running script out/test.js -Acquiring DB from the main thread: -0x7e7fd045401e ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4277 __interceptor_backtrace -0x55fd0fea1bd7 src/util.js.c:477 tf_util_backtrace -0x55fd0fea1c7f src/util.js.c:434 tf_util_backtrace_string -0x55fd0fe12aec src/ssb.c:2260 _tf_ssb_assert_not_main_thread -0x55fd0fe1ba1e src/ssb.c:2270 tf_ssb_acquire_db_reader -0x55fd0fdd4851 src/database.js.c:102 _database_get -0x55fd100cc169 deps/quickjs/quickjs.c:15913 js_call_c_function -0x55fd0ffde160 deps/quickjs/quickjs.c:16108 JS_CallInternal -0x55fd0ffe8d2c deps/quickjs/quickjs.c:16515 JS_CallInternal -0x55fd1012adc4 deps/quickjs/quickjs.c:18823 async_func_resume -0x55fd101402e6 deps/quickjs/quickjs.c:19095 js_async_function_resume -0x55fd10153af3 deps/quickjs/quickjs.c:19191 js_async_function_call -0x55fd101540bd deps/quickjs/quickjs.c:28737 js_execute_sync_module -0x55fd10155c32 deps/quickjs/quickjs.c:28849 js_inner_module_evaluation -0x55fd10156d6a deps/quickjs/quickjs.c:28896 js_evaluate_module -0x55fd101579ee deps/quickjs/quickjs.c:34221 JS_EvalFunctionInternal -0x55fd101596bf deps/quickjs/quickjs.c:34346 __JS_EvalInternal -0x55fd1001fd7c deps/quickjs/quickjs.c:34364 JS_EvalInternal -0x55fd1001fe03 deps/quickjs/quickjs.c:34398 JS_EvalThis -0x55fd1001fea5 deps/quickjs/quickjs.c:34405 JS_Eval -0x55fd0fe81749 src/task.c:423 tf_task_execute -0x55fd0fdf99d0 src/main.c:385 _tf_run_task -0x55fd0fdfa58e src/main.c:575 _tf_command_run -0x55fd0fdfae31 src/main.c:781 main -0x7e7fcf229d90 ../sysdeps/nptl/libc_start_call_main.h:58 __libc_start_call_main -0x7e7fcf229e40 ../csu/libc-start.c:128 call_init -0x7e7fcf229e40 ../csu/libc-start.c:379 __libc_start_main_impl -0x55fd0fdd1ed5 (null):0 (null) - -Acquiring DB from the main thread: -0x7e7fd045401e ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4277 __interceptor_backtrace -0x55fd0fea1bd7 src/util.js.c:477 tf_util_backtrace -0x55fd0fea1c7f src/util.js.c:434 tf_util_backtrace_string -0x55fd0fe12aec src/ssb.c:2260 _tf_ssb_assert_not_main_thread -0x55fd0fe1c871 src/ssb.c:2308 tf_ssb_acquire_db_writer -0x55fd0fdd511b src/database.js.c:127 _database_set -0x55fd100cc169 deps/quickjs/quickjs.c:15913 js_call_c_function -0x55fd0ffde160 deps/quickjs/quickjs.c:16108 JS_CallInternal -0x55fd0ffe8d2c deps/quickjs/quickjs.c:16515 JS_CallInternal -0x55fd1012adc4 deps/quickjs/quickjs.c:18823 async_func_resume -0x55fd101402e6 deps/quickjs/quickjs.c:19095 js_async_function_resume -0x55fd10153af3 deps/quickjs/quickjs.c:19191 js_async_function_call -0x55fd101540bd deps/quickjs/quickjs.c:28737 js_execute_sync_module -0x55fd10155c32 deps/quickjs/quickjs.c:28849 js_inner_module_evaluation -0x55fd10156d6a deps/quickjs/quickjs.c:28896 js_evaluate_module -0x55fd101579ee deps/quickjs/quickjs.c:34221 JS_EvalFunctionInternal -0x55fd101596bf deps/quickjs/quickjs.c:34346 __JS_EvalInternal -0x55fd1001fd7c deps/quickjs/quickjs.c:34364 JS_EvalInternal -0x55fd1001fe03 deps/quickjs/quickjs.c:34398 JS_EvalThis -0x55fd1001fea5 deps/quickjs/quickjs.c:34405 JS_Eval -0x55fd0fe81749 src/task.c:423 tf_task_execute -0x55fd0fdf99d0 src/main.c:385 _tf_run_task -0x55fd0fdfa58e src/main.c:575 _tf_command_run -0x55fd0fdfae31 src/main.c:781 main -0x7e7fcf229d90 ../sysdeps/nptl/libc_start_call_main.h:58 __libc_start_call_main -0x7e7fcf229e40 ../csu/libc-start.c:128 call_init -0x7e7fcf229e40 ../csu/libc-start.c:379 __libc_start_main_impl -0x55fd0fdd1ed5 (null):0 (null) - -Acquiring DB from the main thread: -0x7e7fd045401e ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4277 __interceptor_backtrace -0x55fd0fea1bd7 src/util.js.c:477 tf_util_backtrace -0x55fd0fea1c7f src/util.js.c:434 tf_util_backtrace_string -0x55fd0fe12aec src/ssb.c:2260 _tf_ssb_assert_not_main_thread -0x55fd0fe1ba1e src/ssb.c:2270 tf_ssb_acquire_db_reader -0x55fd0fdd4851 src/database.js.c:102 _database_get -0x55fd100cc169 deps/quickjs/quickjs.c:15913 js_call_c_function -0x55fd0ffde160 deps/quickjs/quickjs.c:16108 JS_CallInternal -0x55fd0ffe8d2c deps/quickjs/quickjs.c:16515 JS_CallInternal -0x55fd1012adc4 deps/quickjs/quickjs.c:18823 async_func_resume -0x55fd101402e6 deps/quickjs/quickjs.c:19095 js_async_function_resume -0x55fd10153af3 deps/quickjs/quickjs.c:19191 js_async_function_call -0x55fd101540bd deps/quickjs/quickjs.c:28737 js_execute_sync_module -0x55fd10155c32 deps/quickjs/quickjs.c:28849 js_inner_module_evaluation -0x55fd10156d6a deps/quickjs/quickjs.c:28896 js_evaluate_module -0x55fd101579ee deps/quickjs/quickjs.c:34221 JS_EvalFunctionInternal -0x55fd101596bf deps/quickjs/quickjs.c:34346 __JS_EvalInternal -0x55fd1001fd7c deps/quickjs/quickjs.c:34364 JS_EvalInternal -0x55fd1001fe03 deps/quickjs/quickjs.c:34398 JS_EvalThis -0x55fd1001fea5 deps/quickjs/quickjs.c:34405 JS_Eval -0x55fd0fe81749 src/task.c:423 tf_task_execute -0x55fd0fdf99d0 src/main.c:385 _tf_run_task -0x55fd0fdfa58e src/main.c:575 _tf_command_run -0x55fd0fdfae31 src/main.c:781 main -0x7e7fcf229d90 ../sysdeps/nptl/libc_start_call_main.h:58 __libc_start_call_main -0x7e7fcf229e40 ../csu/libc-start.c:128 call_init -0x7e7fcf229e40 ../csu/libc-start.c:379 __libc_start_main_impl -0x55fd0fdd1ed5 (null):0 (null) - -Acquiring DB from the main thread: -0x7e7fd045401e ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4277 __interceptor_backtrace -0x55fd0fea1bd7 src/util.js.c:477 tf_util_backtrace -0x55fd0fea1c7f src/util.js.c:434 tf_util_backtrace_string -0x55fd0fe12aec src/ssb.c:2260 _tf_ssb_assert_not_main_thread -0x55fd0fe1c871 src/ssb.c:2308 tf_ssb_acquire_db_writer -0x55fd0fdd511b src/database.js.c:127 _database_set -0x55fd100cc169 deps/quickjs/quickjs.c:15913 js_call_c_function -0x55fd0ffde160 deps/quickjs/quickjs.c:16108 JS_CallInternal -0x55fd0ffe8d2c deps/quickjs/quickjs.c:16515 JS_CallInternal -0x55fd1012adc4 deps/quickjs/quickjs.c:18823 async_func_resume -0x55fd101402e6 deps/quickjs/quickjs.c:19095 js_async_function_resume -0x55fd10153af3 deps/quickjs/quickjs.c:19191 js_async_function_call -0x55fd101540bd deps/quickjs/quickjs.c:28737 js_execute_sync_module -0x55fd10155c32 deps/quickjs/quickjs.c:28849 js_inner_module_evaluation -0x55fd10156d6a deps/quickjs/quickjs.c:28896 js_evaluate_module -0x55fd101579ee deps/quickjs/quickjs.c:34221 JS_EvalFunctionInternal -0x55fd101596bf deps/quickjs/quickjs.c:34346 __JS_EvalInternal -0x55fd1001fd7c deps/quickjs/quickjs.c:34364 JS_EvalInternal -0x55fd1001fe03 deps/quickjs/quickjs.c:34398 JS_EvalThis -0x55fd1001fea5 deps/quickjs/quickjs.c:34405 JS_Eval -0x55fd0fe81749 src/task.c:423 tf_task_execute -0x55fd0fdf99d0 src/main.c:385 _tf_run_task -0x55fd0fdfa58e src/main.c:575 _tf_command_run -0x55fd0fdfae31 src/main.c:781 main -0x7e7fcf229d90 ../sysdeps/nptl/libc_start_call_main.h:58 __libc_start_call_main -0x7e7fcf229e40 ../csu/libc-start.c:128 call_init -0x7e7fcf229e40 ../csu/libc-start.c:379 __libc_start_main_impl -0x55fd0fdd1ed5 (null):0 (null) - -Acquiring DB from the main thread: -0x7e7fd045401e ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4277 __interceptor_backtrace -0x55fd0fea1bd7 src/util.js.c:477 tf_util_backtrace -0x55fd0fea1c7f src/util.js.c:434 tf_util_backtrace_string -0x55fd0fe12aec src/ssb.c:2260 _tf_ssb_assert_not_main_thread -0x55fd0fe1c871 src/ssb.c:2308 tf_ssb_acquire_db_writer -0x55fd0fdd511b src/database.js.c:127 _database_set -0x55fd100cc169 deps/quickjs/quickjs.c:15913 js_call_c_function -0x55fd0ffde160 deps/quickjs/quickjs.c:16108 JS_CallInternal -0x55fd0ffe8d2c deps/quickjs/quickjs.c:16515 JS_CallInternal -0x55fd1012adc4 deps/quickjs/quickjs.c:18823 async_func_resume -0x55fd101402e6 deps/quickjs/quickjs.c:19095 js_async_function_resume -0x55fd10153af3 deps/quickjs/quickjs.c:19191 js_async_function_call -0x55fd101540bd deps/quickjs/quickjs.c:28737 js_execute_sync_module -0x55fd10155c32 deps/quickjs/quickjs.c:28849 js_inner_module_evaluation -0x55fd10156d6a deps/quickjs/quickjs.c:28896 js_evaluate_module -0x55fd101579ee deps/quickjs/quickjs.c:34221 JS_EvalFunctionInternal -0x55fd101596bf deps/quickjs/quickjs.c:34346 __JS_EvalInternal -0x55fd1001fd7c deps/quickjs/quickjs.c:34364 JS_EvalInternal -0x55fd1001fe03 deps/quickjs/quickjs.c:34398 JS_EvalThis -0x55fd1001fea5 deps/quickjs/quickjs.c:34405 JS_Eval -0x55fd0fe81749 src/task.c:423 tf_task_execute -0x55fd0fdf99d0 src/main.c:385 _tf_run_task -0x55fd0fdfa58e src/main.c:575 _tf_command_run -0x55fd0fdfae31 src/main.c:781 main -0x7e7fcf229d90 ../sysdeps/nptl/libc_start_call_main.h:58 __libc_start_call_main -0x7e7fcf229e40 ../csu/libc-start.c:128 call_init -0x7e7fcf229e40 ../csu/libc-start.c:379 __libc_start_main_impl -0x55fd0fdd1ed5 (null):0 (null) - -Acquiring DB from the main thread: -0x7e7fd045401e ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:4277 __interceptor_backtrace -0x55fd0fea1bd7 src/util.js.c:477 tf_util_backtrace -0x55fd0fea1c7f src/util.js.c:434 tf_util_backtrace_string -0x55fd0fe12aec src/ssb.c:2260 _tf_ssb_assert_not_main_thread -0x55fd0fe1ba1e src/ssb.c:2270 tf_ssb_acquire_db_reader -0x55fd0fdd4466 src/database.js.c:230 _database_get_all -0x55fd100cc169 deps/quickjs/quickjs.c:15913 js_call_c_function -0x55fd0ffde160 deps/quickjs/quickjs.c:16108 JS_CallInternal -0x55fd0ffe8d2c deps/quickjs/quickjs.c:16515 JS_CallInternal -0x55fd1012adc4 deps/quickjs/quickjs.c:18823 async_func_resume -0x55fd101402e6 deps/quickjs/quickjs.c:19095 js_async_function_resume -0x55fd10153af3 deps/quickjs/quickjs.c:19191 js_async_function_call -0x55fd101540bd deps/quickjs/quickjs.c:28737 js_execute_sync_module -0x55fd10155c32 deps/quickjs/quickjs.c:28849 js_inner_module_evaluation -0x55fd10156d6a deps/quickjs/quickjs.c:28896 js_evaluate_module -0x55fd101579ee deps/quickjs/quickjs.c:34221 JS_EvalFunctionInternal -0x55fd101596bf deps/quickjs/quickjs.c:34346 __JS_EvalInternal -0x55fd1001fd7c deps/quickjs/quickjs.c:34364 JS_EvalInternal -0x55fd1001fe03 deps/quickjs/quickjs.c:34398 JS_EvalThis -0x55fd1001fea5 deps/quickjs/quickjs.c:34405 JS_Eval -0x55fd0fe81749 src/task.c:423 tf_task_execute -0x55fd0fdf99d0 src/main.c:385 _tf_run_task -0x55fd0fdfa58e src/main.c:575 _tf_command_run -0x55fd0fdfae31 src/main.c:781 main -0x7e7fcf229d90 ../sysdeps/nptl/libc_start_call_main.h:58 __libc_start_call_main -0x7e7fcf229e40 ../csu/libc-start.c:128 call_init -0x7e7fcf229e40 ../csu/libc-start.c:379 __libc_start_main_impl -0x55fd0fdd1ed5 (null):0 (null) - -tf_ssb_destroy -Waiting for closes. -Waiting for rpc. -Closing connections. -Closed. -uv loop closed. -Goodbye. -_tf_run_task is done. Goodbye. -exepath is /home/cory/src/tildefriends/out/debug/tildefriends -setting zip path to (null) -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -prepare failed: no such table: properties -prepare failed: no such table: properties -will delete more blobs in 30000 ms -Running script out/test.js -exepath is /home/cory/src/tildefriends/out/debug/tildefriends -exepath is /home/cory/src/tildefriends/out/debug/tildefriends -setting zip path to (null) -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -prepare failed: no such table: properties -prepare failed: no such table: properties -will delete more blobs in 30000 ms -Running script out/test.js -Task[0x626000000108:out/test.js]> hi -tf_ssb_destroy -Waiting for closes. -Waiting for rpc. -Closing connections. -Closed. -uv loop closed. -Goodbye. -_tf_run_task is done. Goodbye. -exepath is /home/cory/src/tildefriends/out/debug/tildefriends -setting zip path to (null) -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -prepare failed: no such table: properties -prepare failed: no such table: properties -will delete more blobs in 30000 ms -Running script out/test.js -tf_ssb_destroy -Waiting for closes. -Waiting for rpc. -Closing connections. -Closed. -uv loop closed. -Goodbye. -_tf_run_task is done. Goodbye. -exepath is /home/cory/src/tildefriends/out/debug/tildefriends -setting zip path to (null) -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -prepare failed: no such table: properties -prepare failed: no such table: properties -will delete more blobs in 30000 ms -Running script out/bad.js -ERROR: ReferenceError: Could not load 'out/missing.js'. - -Reported an error. -tf_ssb_destroy -Waiting for closes. -Waiting for rpc. -Closing connections. -Closed. -uv loop closed. -Goodbye. -_tf_run_task is done. Goodbye. -exepath is /home/cory/src/tildefriends/out/debug/tildefriends -setting zip path to (null) -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -prepare failed: no such table: properties -prepare failed: no such table: properties -will delete more blobs in 30000 ms -Running script out/test.js -tf_ssb_destroy -Waiting for closes. -Waiting for rpc. -Closing connections. -Closed. -uv loop closed. -Goodbye. -_tf_run_task is done. Goodbye. -exepath is /home/cory/src/tildefriends/out/debug/tildefriends -setting zip path to (null) -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -prepare failed: no such table: properties -prepare failed: no such table: properties -will delete more blobs in 30000 ms -Running script out/test.js -Task[0x626000000108:out/test.js]> Hi -Task[0x626000000108:out/test.js]> 3 -tf_ssb_destroy -Waiting for closes. -Waiting for rpc. -Closing connections. -Closed. -uv loop closed. -Goodbye. -_tf_run_task is done. Goodbye. -exepath is /home/cory/src/tildefriends/out/debug/tildefriends -setting zip path to (null) -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -prepare failed: no such table: properties -prepare failed: no such table: properties -will delete more blobs in 30000 ms -Running script out/test.js -Task[0x626000000108:out/test.js]> child started -Task[0x626000000108:out/test.js]> input 0,1,2,3,4,5,6,7,8,9 10 10 -Task[0x626000000108:out/test.js]> output 0,1,2,3,4,5,6,7,8,9 10 10 -Task[0x626000000108:out/test.js]> 0 -Task[0x626000000108:out/test.js]> 1 -Task[0x626000000108:out/test.js]> 2 -Task[0x626000000108:out/test.js]> 3 -Task[0x626000000108:out/test.js]> 4 -Task[0x626000000108:out/test.js]> 5 -Task[0x626000000108:out/test.js]> 6 -Task[0x626000000108:out/test.js]> 7 -Task[0x626000000108:out/test.js]> 8 -Task[0x626000000108:out/test.js]> 9 -exepath is /home/cory/src/tildefriends/out/debug/tildefriends -setting zip path to (null) -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -prepare failed: no such table: properties -prepare failed: no such table: properties -will delete more blobs in 30000 ms -Running script out/test.js -Task[0x626000000108:out/test.js]> get exports -Task[0x626000000108:out/test.js]> calling export -Task[0x626000000108:out/test.js]> 1.2 -exepath is /home/cory/src/tildefriends/out/debug/tildefriends -setting zip path to (null) -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -prepare failed: no such table: properties -prepare failed: no such table: properties -will delete more blobs in 30000 ms -Running script out/test.js -Task[0x626000000108:out/test.js]> connecting -Task[0x626000000108:out/test.js]> before connect false -Task[0x626000000108:out/test.js]> noDelay false -Task[0x626000000108:out/test.js]> connecting -Task[0x626000000108:out/test.js]> before connect false -Task[0x626000000108:out/test.js]> noDelay false -Task[0x626000000108:out/test.js]> connecting s3 -Task[0x626000000108:out/test.js]> before connect false -Task[0x626000000108:out/test.js]> noDelay false -Task[0x626000000108:out/test.js]> caught -Task[0x626000000108:out/test.js]> InternalError: uv_tcp_connect: connection refused -Task[0x626000000108:out/test.js]> connected www.unprompted.com 80 true -Task[0x626000000108:out/test.js]> 66.175.209.35 -Task[0x626000000108:out/test.js]> connected www.unprompted.com 443 -Task[0x626000000108:out/test.js]> closed 1 -Task[0x626000000108:out/test.js]> read 543 -Task[0x626000000108:out/test.js]> read null -Task[0x626000000108:out/test.js]> ready -Task[0x626000000108:out/test.js]> 66.175.209.35 -Task[0x626000000108:out/test.js]> read 492 -Task[0x626000000108:out/test.js]> read null -tf_ssb_destroy -Waiting for closes. -Waiting for rpc. -Closing connections. -Closed. -uv loop closed. -Goodbye. -_tf_run_task is done. Goodbye. -exepath is /home/cory/src/tildefriends/out/debug/tildefriends -setting zip path to (null) -will delete more blobs in 30000 ms -Running script out/test.js -Task[0x626000000108:out/test.js]> expected error InternalError: Failed to open out/missing.txt for read: no such file or directory -tf_ssb_destroy -Waiting for closes. -Waiting for rpc. -Closing connections. -Closed. -uv loop closed. -Goodbye. -_tf_run_task is done. Goodbye. -exepath is /home/cory/src/tildefriends/out/debug/tildefriends -setting zip path to (null) -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -prepare failed: no such table: properties -prepare failed: no such table: properties -will delete more blobs in 30000 ms -Running script out/test.js -Task[0x626000000108:out/test.js]> aGVsbG8= -tf_ssb_destroy -Waiting for closes. -Waiting for rpc. -Closing connections. -Closed. -uv loop closed. -Goodbye. -_tf_run_task is done. Goodbye. -mory: -s out/test.js --ssb-port=0 --http-port=0 --https-port=0 -[pass] nop -== running test exception == -out/debug/tildefriends run --db-path=:memory: -s out/test.js --ssb-port=0 --http-port=0 --https-port=0 -result = 65280 -[pass] exception -== running test sandbox == -out/debug/tildefriends run --db-path=:memory: -s out/test.js --ssb-port=0 --http-port=0 --https-port=0 -[pass] sandbox -== running test child == -out/debug/tildefriends run --db-path=:memory: -s out/test.js --ssb-port=0 --http-port=0 --https-port=0 -[pass] child -== running test promise == -out/debug/tildefriends run --db-path=:memory: -s out/test.js --ssb-port=0 --http-port=0 --https-port=0 -[pass] promise -== running test promise_remote_throw == -out/debug/tildefriends run --db-path=:memory: -s out/test.js --ssb-port=0 --http-port=0 --https-port=0 -[pass] promise_remote_throw -== running test promise_remote_reject == -out/debug/tildefriends run --db-path=:memory: -s out/test.js --ssb-port=0 --http-port=0 --https-port=0 -[pass] promise_remote_reject -== running test database == -out/debug/tildefriends run --db-path=out/test_db0.sqlite -s out/test.js --ssb-port=0 --http-port=0 --https-port=0 -returned 0 -[pass] database -== running test this == -out/debug/tildefriends run --db-path=:memory: -s out/test.js --ssb-port=0 --http-port=0 --https-port=0 -returned 0 -[pass] this -== running test await == -out/debug/tildefriends run --db-path=:memory: -s out/test.js --ssb-port=0 --http-port=0 --https-port=0 -returned 0 -[pass] await -== running test import == -out/debug/tildefriends run --db-path=:memory: -s out/test.js --ssb-port=0 --http-port=0 --https-port=0 -returned 0 -out/debug/tildefriends run --db-path=:memory: -s out/bad.js --ssb-port=0 --http-port=0 --https-port=0 -returned 255 -[pass] import -== running test exit == -out/debug/tildefriends run --db-path=:memory: -s out/test.js --ssb-port=0 --http-port=0 --https-port=0 -returned 0 -[pass] exit -== running test icu == -out/debug/tildefriends run --db-path=:memory: -s out/test.js --ssb-port=0 --http-port=0 --https-port=0 -returned 0 -[pass] icu -== running test uint8array == -out/debug/tildefriends run --db-path=:memory: -s out/test.js --ssb-port=0 --http-port=0 --https-port=0 -returned 0 -[pass] uint8array -== running test float == -out/debug/tildefriends run --db-path=:memory: -s out/test.js --ssb-port=0 --http-port=0 --https-port=0 -[pass] float -== running test socket == -out/debug/tildefriends run --db-path=:memory: -s out/test.js --ssb-port=0 --http-port=0 --https-port=0 -returned 0 -[pass] socket -== running test file == -out/debug/tildefriends run --db-path=out/test.db -s out/test.js --ssb-port=0 --http-port=0 --https-port=0 -returned 0 -[pass] file -== running test b64 == -out/debug/tildefriends run --db-path=:memory: -s out/test.js --ssb-port=0 --http-port=0 --https-port=0 -returned 0 -[pass] b64 -== running test rooms == -Testing Rooms. -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -ID @VXbugSv722f0Iy6uKdYYs1HIRYeNR+/eS76+7s9jL1k=.ed25519, @WkLs3nXZD7OGE1m3JCfTjIV44YIZLpDoVcks3m5Rqu0=.ed25519, @OZmTKyFxx1nCYZY3HPxfZAVn5iKYLYCqkKeP7CA6VSo=.ed25519 -Waiting for connection. -callback1 change=0 connection=0x7c20e16da808 -conns = 0 0 0 -callback2 change=0 connection=0x7c20e0cb7808 -conns = 0 0 0 -callback0 change=0 connection=0x7c20e0294808 -conns = 0 0 0 -callback0 change=0 connection=0x7c20df871808 -conns = 0 0 0 -callback0 change=1 connection=0x7c20e0294808 -conns = 1 0 0 -callback0 change=3 connection=0x7c20e0294808 -conns = 1 0 0 -callback1 change=1 connection=0x7c20e16da808 -conns = 1 1 0 -callback1 change=3 connection=0x7c20e16da808 -conns = 1 1 0 -callback1 change=3 connection=0x7c20e16da808 -conns = 1 1 0 -callback1 change=3 connection=0x7c20e16da808 -conns = 1 1 0 -callback0 change=1 connection=0x7c20df871808 -conns = 2 1 0 -callback0 change=3 connection=0x7c20df871808 -conns = 2 1 0 -callback1 change=3 connection=0x7c20e16da808 -conns = 2 1 0 -callback2 change=1 connection=0x7c20e0cb7808 -conns = 2 1 1 -callback2 change=3 connection=0x7c20e0cb7808 -conns = 2 1 1 -callback2 change=3 connection=0x7c20e0cb7808 -conns = 2 1 1 -callback2 change=3 connection=0x7c20e0cb7808 -conns = 2 1 1 -Stopped broadcasts. -Waiting for broadcasts. -callback0 change=3 connection=0x7c20e0294808 -conns = 2 1 1 -callback2 change=3 connection=0x7c20e0cb7808 -conns = 2 1 1 -callback0 change=3 connection=0x7c20e0294808 -conns = 2 1 1 -callback0 change=3 connection=0x7c20e0294808 -conns = 2 1 1 -callback0 change=3 connection=0x7c20df871808 -conns = 2 1 1 -callback0 change=3 connection=0x7c20df871808 -conns = 2 1 1 -callback0 change=3 connection=0x7c20df871808 -conns = 2 1 1 -callback1 change=3 connection=0x7c20e16da808 -conns = 2 1 1 -callback1 change=3 connection=0x7c20e16da808 -conns = 2 1 1 -callback0 change=3 connection=0x7c20e0294808 -conns = 2 1 1 -callback0 change=3 connection=0x7c20e0294808 -conns = 2 1 1 -callback2 change=3 connection=0x7c20e0cb7808 -conns = 2 1 1 -callback2 change=3 connection=0x7c20e0cb7808 -conns = 2 1 1 -callback0 change=3 connection=0x7c20df871808 -conns = 2 1 1 -callback0 change=3 connection=0x7c20df871808 -conns = 2 1 1 -callback0 change=3 connection=0x7c20df871808 -conns = 2 1 1 -BROADCASTS 0 0 0 -callback0 change=3 connection=0x7c20e0294808 -conns = 2 1 1 -BROADCASTS 0 0 0 -BROADCASTS 0 1 0 -BROADCASTS 0 1 1 -callback1 change=3 connection=0x7c20e16da808 -conns = 2 1 1 -callback1 change=0 connection=0x7c20deae6808 -conns = 2 1 1 -callback1 change=3 connection=0x7c20e16da808 -conns = 2 1 1 -tun0 = 0x7c20deae6808 -Done. -callback0 change=3 connection=0x7c20e0294808 -conns = 2 1 1 -callback0 change=3 connection=0x7c20df871808 -conns = 2 1 1 -callback0 change=3 connection=0x7c20e0294808 -conns = 2 1 1 -callback0 change=3 connection=0x7c20df871808 -conns = 2 1 1 -callback2 change=3 connection=0x7c20e0cb7808 -conns = 2 1 1 -callback2 change=0 connection=0x7c20de04a808 -conns = 2 1 1 -callback2 change=3 connection=0x7c20e0cb7808 -conns = 2 1 1 -callback2 change=1 connection=0x7c20de04a808 -conns = 2 1 2 -callback2 change=3 connection=0x7c20de04a808 -conns = 2 1 2 -callback1 change=1 connection=0x7c20deae6808 -conns = 2 2 2 -callback1 change=3 connection=0x7c20deae6808 -conns = 2 2 2 -callback1 change=3 connection=0x7c20deae6808 -conns = 2 2 2 -callback1 change=3 connection=0x7c20deae6808 -conns = 2 2 2 -Done. -Connection tun0 0x7c20deae6808 is closing: tf_ssb_connection_close. -callback1 change=3 connection=0x7c20deae6808 -conns = 2 1 2 -callback1 change=3 connection=0x7c20deae6808 -conns = 2 1 2 -callback1 change=3 connection=0x7c20deae6808 -conns = 2 1 2 -callback1 change=2 connection=0x7c20deae6808 -conns = 2 1 2 -callback1 change=3 connection=0x7c20e16da808 -conns = 2 1 2 -Connection srv5 0x7c20df871808 is closing: crypto_secretbox_easy close message. -callback0 change=3 connection=0x7c20df871808 -conns = 1 1 2 -callback0 change=3 connection=0x7c20df871808 -conns = 1 1 2 -callback0 change=3 connection=0x7c20df871808 -conns = 1 1 2 -callback0 change=3 connection=0x7c20df871808 -conns = 1 1 2 -callback0 change=3 connection=0x7c20df871808 -conns = 1 1 2 -callback0 change=2 connection=0x7c20df871808 -conns = 1 1 2 -Connection cli2 0x7c20e16da808 is closing: crypto_secretbox_easy close message. -callback1 change=3 connection=0x7c20e16da808 -conns = 1 0 2 -callback1 change=3 connection=0x7c20e16da808 -conns = 1 0 2 -callback1 change=3 connection=0x7c20e16da808 -conns = 1 0 2 -callback1 change=3 connection=0x7c20e16da808 -conns = 1 0 2 -callback1 change=2 connection=0x7c20e16da808 -conns = 1 0 2 -Connection tun1 0x7c20de04a808 is closing: crypto_secretbox_easy close message. -callback2 change=3 connection=0x7c20de04a808 -conns = 1 0 1 -callback2 change=2 connection=0x7c20de04a808 -conns = 1 0 1 -Connection srv4 0x7c20e0294808 is closing: tf_ssb_close_all. -callback0 change=3 connection=0x7c20e0294808 -conns = 0 0 1 -callback0 change=3 connection=0x7c20e0294808 -conns = 0 0 1 -callback0 change=3 connection=0x7c20e0294808 -conns = 0 0 1 -callback0 change=3 connection=0x7c20e0294808 -conns = 0 0 1 -callback0 change=3 connection=0x7c20e0294808 -conns = 0 0 1 -callback0 change=2 connection=0x7c20e0294808 -conns = 0 0 1 -Connection cli3 0x7c20e0cb7808 is closing: tf_ssb_close_all. -callback2 change=3 connection=0x7c20e0cb7808 -conns = 0 0 0 -callback2 change=3 connection=0x7c20e0cb7808 -conns = 0 0 0 -callback2 change=3 connection=0x7c20e0cb7808 -conns = 0 0 0 -callback2 change=3 connection=0x7c20e0cb7808 -conns = 0 0 0 -callback2 change=3 connection=0x7c20e0cb7808 -conns = 0 0 0 -callback2 change=2 connection=0x7c20e0cb7808 -conns = 0 0 0 -tf_ssb_destroy -Waiting for closes. -Waiting for rpc. -Closing connections. -Closed. -uv loop closed. -closing ssb context -tf_ssb_destroy -Waiting for closes. -Waiting for rpc. -Closing connections. -Closed. -uv loop closed. -closing ssb context -tf_ssb_destroy -Waiting for closes. -Waiting for rpc. -Closing connections. -Closed. -uv loop closed. -closing ssb context -[pass] rooms -== running test bench == -Testing following. -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -insert = 11.531131 seconds -Enabling auto-vacuum and performing full vacuum. -All clean. -Populating full-text search... -Done. -Populating messages_refs... -Done. -Generating a new keypair. -Waiting for messages. -Done. -replicate = 5.515292 seconds -Connection cli6 0x7c20e30b7808 is closing: crypto_secretbox_easy close message. -Stopped broadcasts. -Connection srv7 0x7c20e16da808 is closing: end of file. -tf_ssb_destroy -Waiting for closes. -Waiting for rpc. -Closing connections. -Closed. -uv loop closed. -closing ssb context -tf_ssb_destroy -Waiting for closes. -Waiting for rpc. -Closing connections. -Closed. -uv loop closed. -closing ssb context -[pass] bench -== running test auto == -Process exit 0 signal=0. -Process exit 0 signal=0. -[pass] auto -Tests completed. diff --git a/src/database.js.c b/src/database.js.c index 0b09f464..93fc0ba7 100644 --- a/src/database.js.c +++ b/src/database.js.c @@ -4,6 +4,7 @@ #include "mem.h" #include "ssb.h" #include "task.h" +#include "util.js.h" #include "sqlite3.h" @@ -91,57 +92,159 @@ static void _database_finalizer(JSRuntime* runtime, JSValue value) --_database_count; } +typedef struct _database_get_t +{ + const char* id; + const char* key; + size_t key_length; + char* out_value; + size_t out_length; + JSValue promise[2]; +} database_get_t; + +static void _database_get_work(tf_ssb_t* ssb, void* user_data) +{ + database_get_t* work = user_data; + sqlite3_stmt* statement; + sqlite3* db = tf_ssb_acquire_db_reader(ssb); + if (sqlite3_prepare(db, "SELECT value FROM properties WHERE id = ? AND key = ?", -1, &statement, NULL) == SQLITE_OK) + { + if (sqlite3_bind_text(statement, 1, work->id, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, work->key, work->key_length, NULL) == SQLITE_OK && + sqlite3_step(statement) == SQLITE_ROW) + { + size_t length = sqlite3_column_bytes(statement, 0); + char* data = tf_malloc(length + 1); + memcpy(data, sqlite3_column_text(statement, 0), length); + data[length] = '\0'; + work->out_value = data; + work->out_length = length; + } + sqlite3_finalize(statement); + } + tf_ssb_release_db_reader(ssb, db); +} + +static void _database_get_after_work(tf_ssb_t* ssb, int status, void* user_data) +{ + database_get_t* work = user_data; + JSContext* context = tf_ssb_get_context(ssb); + JSValue result = JS_UNDEFINED; + if (work->out_value) + { + result = JS_NewStringLen(context, work->out_value, work->out_length); + } + JSValue error = JS_Call(context, work->promise[0], JS_UNDEFINED, 1, &result); + tf_util_report_error(context, error); + JS_FreeValue(context, error); + JS_FreeValue(context, result); + JS_FreeValue(context, work->promise[0]); + JS_FreeValue(context, work->promise[1]); + tf_free(work->out_value); + tf_free(work); +} + static JSValue _database_get(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { - JSValue entry = JS_UNDEFINED; + JSValue result = JS_UNDEFINED; database_t* database = JS_GetOpaque(this_val, _database_class_id); if (database) { tf_ssb_t* ssb = tf_task_get_ssb(database->task); - sqlite3_stmt* statement; - sqlite3* db = tf_ssb_acquire_db_reader(ssb); - if (sqlite3_prepare(db, "SELECT value FROM properties WHERE id = ? AND key = ?", -1, &statement, NULL) == SQLITE_OK) + + size_t length; + const char* key = JS_ToCStringLen(context, &length, argv[0]); + database_get_t* work = tf_malloc(sizeof(database_get_t) + strlen(database->id) + 1 + length + 1); + *work = (database_get_t) { - size_t length; - const char* keyString = JS_ToCStringLen(context, &length, argv[0]); - if (sqlite3_bind_text(statement, 1, database->id, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, keyString, length, NULL) == SQLITE_OK && - sqlite3_step(statement) == SQLITE_ROW) - { - entry = JS_NewStringLen(context, (const char*)sqlite3_column_text(statement, 0), sqlite3_column_bytes(statement, 0)); - } - JS_FreeCString(context, keyString); - sqlite3_finalize(statement); - } - tf_ssb_release_db_reader(ssb, db); + .id = (const char*)(work + 1), + .key = (const char*)(work + 1) + strlen(database->id) + 1, + .key_length = length, + }; + memcpy((char*)work->id, database->id, strlen(database->id) + 1); + memcpy((char*)work->key, key, length + 1); + JS_FreeCString(context, key); + + tf_ssb_run_work(ssb, _database_get_work, _database_get_after_work, work); + result = JS_NewPromiseCapability(context, work->promise); } - return entry; + return result; +} + +typedef struct _database_set_t +{ + const char* id; + const char* key; + size_t key_length; + const char* value; + size_t value_length; + bool result; + JSValue promise[2]; +} database_set_t; + +static void _database_set_work(tf_ssb_t* ssb, void* user_data) +{ + database_set_t* work = user_data; + sqlite3* db = tf_ssb_acquire_db_writer(ssb); + sqlite3_stmt* statement; + if (sqlite3_prepare(db, "INSERT OR REPLACE INTO properties (id, key, value) VALUES (?1, ?2, ?3)", -1, &statement, NULL) == SQLITE_OK) + { + if (sqlite3_bind_text(statement, 1, work->id, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, work->key, work->key_length, NULL) == SQLITE_OK && + sqlite3_bind_text(statement, 3, work->value, work->value_length, NULL) == SQLITE_OK && sqlite3_step(statement) == SQLITE_OK) + { + work->result = true; + } + sqlite3_finalize(statement); + } + tf_ssb_release_db_writer(ssb, db); +} + +static void _database_set_after_work(tf_ssb_t* ssb, int status, void* user_data) +{ + database_set_t* work = user_data; + JSContext* context = tf_ssb_get_context(ssb); + JSValue result = work->result ? JS_TRUE : JS_UNDEFINED; + JSValue error = JS_Call(context, work->promise[0], JS_UNDEFINED, 1, &result); + tf_util_report_error(context, error); + JS_FreeValue(context, error); + JS_FreeValue(context, result); + JS_FreeValue(context, work->promise[0]); + JS_FreeValue(context, work->promise[1]); + tf_free(work); } static JSValue _database_set(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { + JSValue result = JS_UNDEFINED; database_t* database = JS_GetOpaque(this_val, _database_class_id); if (database) { - sqlite3_stmt* statement; tf_ssb_t* ssb = tf_task_get_ssb(database->task); - sqlite3* db = tf_ssb_acquire_db_writer(ssb); - if (sqlite3_prepare(db, "INSERT OR REPLACE INTO properties (id, key, value) VALUES (?1, ?2, ?3)", -1, &statement, NULL) == SQLITE_OK) + + size_t key_length = 0; + const char* key = JS_ToCStringLen(context, &key_length, argv[0]); + size_t value_length = 0; + const char* value = JS_ToCStringLen(context, &value_length, argv[1]); + + database_set_t* work = tf_malloc(sizeof(database_set_t) + strlen(database->id) + 1 + key_length + 1 + value_length + 1); + *work = (database_set_t) { - size_t keyLength; - const char* keyString = JS_ToCStringLen(context, &keyLength, argv[0]); - size_t valueLength; - const char* valueString = JS_ToCStringLen(context, &valueLength, argv[1]); - if (sqlite3_bind_text(statement, 1, database->id, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, keyString, keyLength, NULL) == SQLITE_OK && - sqlite3_bind_text(statement, 3, valueString, valueLength, NULL) == SQLITE_OK && sqlite3_step(statement) == SQLITE_OK) - { - } - JS_FreeCString(context, keyString); - JS_FreeCString(context, valueString); - sqlite3_finalize(statement); - } - tf_ssb_release_db_writer(ssb, db); + .id = (const char*)(work + 1), + .key = (const char*)(work + 1) + strlen(database->id) + 1, + .value = (const char*)(work + 1) + strlen(database->id) + 1 + key_length + 1, + .key_length = key_length, + .value_length = value_length, + }; + + memcpy((char*)work->id, database->id, strlen(database->id) + 1); + memcpy((char*)work->key, key, key_length + 1); + memcpy((char*)work->value, value, value_length + 1); + + result = JS_NewPromiseCapability(context, work->promise); + tf_ssb_run_work(ssb, _database_set_work, _database_set_after_work, work); + JS_FreeCString(context, key); + JS_FreeCString(context, value); } - return JS_UNDEFINED; + return result; } static JSValue _database_exchange(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) diff --git a/src/tests.c b/src/tests.c index 68dd4463..89386dfd 100644 --- a/src/tests.c +++ b/src/tests.c @@ -266,32 +266,35 @@ static void _test_promise_remote_reject(const tf_test_options_t* options) static void _test_database(const tf_test_options_t* options) { _write_file("out/test.js", - "var db = new Database('testdb');\n" - "if (db.get('a')) {\n" - " exit(1);\n" - "}\n" - "db.set('a', 1);\n" - "if (db.get('a') != 1) {\n" - " exit(2);\n" - "}\n" - "db.set('b', 2);\n" - "db.set('c', 3);\n" + "async function main() {\n" + " var db = new Database('testdb');\n" + " if (await db.get('a')) {\n" + " exit(1);\n" + " }\n" + " await db.set('a', 1);\n" + " if (await db.get('a') != 1) {\n" + " exit(2);\n" + " }\n" + " await db.set('b', 2);\n" + " await db.set('c', 3);\n" "\n" - "var expected = ['a', 'b', 'c'];\n" - "var have = db.getAll();\n" - "for (var i = 0; i < have.length; i++) {\n" - " var item = have[i];\n" - " if (expected.indexOf(item) == -1) {\n" - " print('Did not find ' + item + ' in db.');\n" - " exit(3);\n" - " } else {\n" - " expected.splice(expected.indexOf(item), 1);\n" + " var expected = ['a', 'b', 'c'];\n" + " var have = db.getAll();\n" + " for (var i = 0; i < have.length; i++) {\n" + " var item = have[i];\n" + " if (expected.indexOf(item) == -1) {\n" + " print('Did not find ' + item + ' in db.');\n" + " exit(3);\n" + " } else {\n" + " expected.splice(expected.indexOf(item), 1);\n" + " }\n" + " }\n" + " if (expected.length) {\n" + " print('Expected but did not find: ' + JSON.stringify(expected));\n" + " exit(4);\n" " }\n" "}\n" - "if (expected.length) {\n" - " print('Expected but did not find: ' + JSON.stringify(expected));\n" - " exit(4);\n" - "}\n"); + "main();"); char command[256]; unlink("out/test_db0.sqlite");