kuboon
kuboon3mo ago

Can I use deno KV in worker?

It looks work, but does not persist at all. See my sample code below. Q1. why "key1" is not listed in my worker? Q2. why "key2" always 1?
deno -v
deno 2.4.4
deno run --allow-read=. kvTest.ts
I am NOT in a web worker { key: [ "key1" ], value: 8, versionstamp: "00000000000000e00000" } I am in a web worker { key: [ "key2" ], value: 1, versionstamp: "00000000000000090000" }
kvTest.ts
const kv = await Deno.openKv();
if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {
console.log('I am in a web worker');
await increment("key2")
await listAll();
} else {
console.log('I am NOT in a web worker');
await increment("key1")
await listAll();
new Worker(import.meta.url, { type: "module" });
}

async function increment(key: string) {
const current = await kv.get([key]);
await kv.atomic().check(current).set([key], (current.value as number ?? 0) + 1).commit();
}
async function listAll(){
for await (const entry of kv.list({ prefix: [] })) {
console.log(entry);
}
}
kvTest.ts
const kv = await Deno.openKv();
if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {
console.log('I am in a web worker');
await increment("key2")
await listAll();
} else {
console.log('I am NOT in a web worker');
await increment("key1")
await listAll();
new Worker(import.meta.url, { type: "module" });
}

async function increment(key: string) {
const current = await kv.get([key]);
await kv.atomic().check(current).set([key], (current.value as number ?? 0) + 1).commit();
}
async function listAll(){
for await (const entry of kv.list({ prefix: [] })) {
console.log(entry);
}
}
3 Replies
Leokuma
Leokuma3mo ago
If your idea is to "share" a DB with a worker, you should always specify the DB file path, like await Deno.openKv("mydb.db") If you call Deno.openKv() without arguments, a new DB will be created for each worker instance because they are isolated from each another
kuboon
kuboonOP2mo ago
Thank you @Leokuma . Passing "mydb.db" did successful. Then I found another question. When I prepare "mydb.db" in main thread first, it can be opened in a worker, but it will fail to create new KV file in a worker. Minimum sample here:
function inWorker() {
return typeof WorkerGlobalScope !== "undefined" &&
self instanceof WorkerGlobalScope;
}

if (!inWorker()) {
new Worker(import.meta.url, { type: "module" });
} else {
console.log("I am in a web worker");
// Deno.createSync("test.kv"); // uncomment this to go success
await Deno.openKv("test.kv");
}
function inWorker() {
return typeof WorkerGlobalScope !== "undefined" &&
self instanceof WorkerGlobalScope;
}

if (!inWorker()) {
new Worker(import.meta.url, { type: "module" });
} else {
console.log("I am in a web worker");
// Deno.createSync("test.kv"); // uncomment this to go success
await Deno.openKv("test.kv");
}
I am in a web worker error: Uncaught (in worker "") (in promise) NotFound: No such file or directory (os error 2)
>
Leokuma
Leokuma2mo ago
I guess that's a safety measure Try like this:
Deno.openKv(import.meta.dirname + "/test.kv");
Deno.openKv(import.meta.dirname + "/test.kv");

Did you find this page helpful?