@based/db 0.0.58 → 0.0.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/darwin_aarch64/libnode-v20.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v21.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v22.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v23.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v24.node +0 -0
- package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
- package/dist/lib/linux_aarch64/libselva.so +0 -0
- package/dist/lib/linux_x86_64/libselva.so +0 -0
- package/dist/src/hooks.js +2 -3
- package/dist/src/index.d.ts +2 -6
- package/dist/src/server/DbWorker.d.ts +2 -1
- package/dist/src/server/DbWorker.js +26 -1
- package/dist/src/server/index.d.ts +4 -4
- package/dist/src/server/index.js +2 -0
- package/dist/src/server/migrate/index.js +10 -4
- package/dist/src/server/save.js +108 -75
- package/dist/src/server/start.d.ts +5 -2
- package/dist/src/server/start.js +17 -11
- package/dist/src/server/worker.js +2 -7
- package/dist/src/types.d.ts +6 -0
- package/package.json +1 -1
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/dist/src/hooks.js
CHANGED
|
@@ -14,12 +14,11 @@ export const getDefaultHooks = (server, subInterval = 200) => {
|
|
|
14
14
|
onData(res);
|
|
15
15
|
}
|
|
16
16
|
else if (res.byteLength === 1 && res[0] === 0) {
|
|
17
|
-
|
|
18
|
-
// ignore update and stop polling
|
|
17
|
+
server.emit('info', `[${displayTarget(q.def)}] Subscribe schema mismatch - should resolve after update`);
|
|
19
18
|
return;
|
|
20
19
|
}
|
|
21
20
|
else {
|
|
22
|
-
const def =
|
|
21
|
+
const def = q.def;
|
|
23
22
|
let name = picocolors.red(`QueryError[${displayTarget(def)}]\n`);
|
|
24
23
|
name += ` Incorrect buffer received in subscription (maybe server not started ${res.byteLength}) bytes\n`;
|
|
25
24
|
onError(new Error(name));
|
package/dist/src/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { DbServer } from './server/index.js';
|
|
|
4
4
|
import { DbClient } from './client/index.js';
|
|
5
5
|
import { getDefaultHooks } from './hooks.js';
|
|
6
6
|
import { Emitter } from './shared/Emitter.js';
|
|
7
|
+
import { BasedDbOpts } from './types.js';
|
|
7
8
|
export * from './client/modify/modify.js';
|
|
8
9
|
export { compress, decompress };
|
|
9
10
|
export { ModifyCtx };
|
|
@@ -24,12 +25,7 @@ export declare class BasedDb extends Emitter {
|
|
|
24
25
|
server: DbServer;
|
|
25
26
|
fileSystemPath: string;
|
|
26
27
|
maxModifySize: number;
|
|
27
|
-
constructor(opts:
|
|
28
|
-
path: string;
|
|
29
|
-
maxModifySize?: number;
|
|
30
|
-
debug?: boolean | 'server' | 'client';
|
|
31
|
-
saveIntervalInSeconds?: number;
|
|
32
|
-
});
|
|
28
|
+
constructor(opts: BasedDbOpts);
|
|
33
29
|
create: DbClient['create'];
|
|
34
30
|
copy: DbClient['copy'];
|
|
35
31
|
update: DbClient['update'];
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Worker, MessagePort } from 'node:worker_threads';
|
|
2
2
|
import { DbServer } from './index.js';
|
|
3
3
|
export declare class DbWorker {
|
|
4
|
-
constructor(address: BigInt, db: DbServer);
|
|
4
|
+
constructor(address: BigInt, db: DbServer, workerIndex: number);
|
|
5
5
|
db: DbServer;
|
|
6
6
|
channel: MessagePort;
|
|
7
7
|
worker: Worker;
|
|
8
8
|
resolvers: any[];
|
|
9
|
+
readyPromise: Promise<true>;
|
|
9
10
|
callback: (resolve: any) => void;
|
|
10
11
|
updateCtx(address: BigInt): Promise<void>;
|
|
11
12
|
getQueryBuf(buf: Uint8Array): Promise<Uint8Array>;
|
|
@@ -5,7 +5,7 @@ const __filename = fileURLToPath(import.meta.url);
|
|
|
5
5
|
const __dirname = dirname(__filename);
|
|
6
6
|
const workerPath = join(__dirname, 'worker.js');
|
|
7
7
|
export class DbWorker {
|
|
8
|
-
constructor(address, db) {
|
|
8
|
+
constructor(address, db, workerIndex) {
|
|
9
9
|
const { port1, port2 } = new MessageChannel();
|
|
10
10
|
this.db = db;
|
|
11
11
|
this.channel = port1;
|
|
@@ -17,6 +17,30 @@ export class DbWorker {
|
|
|
17
17
|
},
|
|
18
18
|
transferList: [port2],
|
|
19
19
|
});
|
|
20
|
+
this.readyPromise = new Promise((resolve) => {
|
|
21
|
+
const onReady = (msg) => {
|
|
22
|
+
if (msg === 'READY') {
|
|
23
|
+
this.worker.off('message', onReady);
|
|
24
|
+
resolve(true);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
this.worker.on('message', onReady);
|
|
28
|
+
});
|
|
29
|
+
this.worker.on('error', (err) => {
|
|
30
|
+
console.error('error in query worker:', err);
|
|
31
|
+
this.worker.terminate();
|
|
32
|
+
});
|
|
33
|
+
this.worker.on('exit', (code) => {
|
|
34
|
+
if (!this.db.stopped) {
|
|
35
|
+
console.info('unexpected exit query worker with code:', code);
|
|
36
|
+
const err = new Error('Worker could not process query');
|
|
37
|
+
for (const resolve of this.resolvers) {
|
|
38
|
+
resolve(err);
|
|
39
|
+
}
|
|
40
|
+
this.resolvers = [];
|
|
41
|
+
this.db.workers[workerIndex] = new DbWorker(address, db, workerIndex);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
20
44
|
port1.on('message', (buf) => {
|
|
21
45
|
this.resolvers.shift()(new Uint8Array(buf));
|
|
22
46
|
this.db.onQueryEnd();
|
|
@@ -26,6 +50,7 @@ export class DbWorker {
|
|
|
26
50
|
channel;
|
|
27
51
|
worker;
|
|
28
52
|
resolvers = [];
|
|
53
|
+
readyPromise;
|
|
29
54
|
callback = (resolve) => {
|
|
30
55
|
this.db.processingQueries++;
|
|
31
56
|
this.resolvers.push(resolve);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { LangName, StrictSchema } from '@based/schema';
|
|
2
2
|
import { createTree } from './csmt/index.js';
|
|
3
|
+
import { StartOpts } from './start.js';
|
|
3
4
|
import { CsmtNodeRange } from './tree.js';
|
|
4
5
|
import { TransformFns } from './migrate/index.js';
|
|
5
6
|
import exitHook from 'exit-hook';
|
|
@@ -17,6 +18,7 @@ export declare class DbServer extends DbShared {
|
|
|
17
18
|
modifyDirtyRanges: Float64Array;
|
|
18
19
|
dbCtxExternal: any;
|
|
19
20
|
migrating: number;
|
|
21
|
+
saveInProgress: boolean;
|
|
20
22
|
fileSystemPath: string;
|
|
21
23
|
merkleTree: ReturnType<typeof createTree<CsmtNodeRange>>;
|
|
22
24
|
dirtyRanges: Set<number>;
|
|
@@ -34,15 +36,13 @@ export declare class DbServer extends DbShared {
|
|
|
34
36
|
unlistenExit: ReturnType<typeof exitHook>;
|
|
35
37
|
saveIntervalInSeconds?: number;
|
|
36
38
|
saveInterval?: NodeJS.Timeout;
|
|
39
|
+
delayInMs?: number;
|
|
37
40
|
constructor({ path, debug, saveIntervalInSeconds, }: {
|
|
38
41
|
path: string;
|
|
39
42
|
debug?: boolean;
|
|
40
43
|
saveIntervalInSeconds?: number;
|
|
41
44
|
});
|
|
42
|
-
start(opts?:
|
|
43
|
-
clean?: boolean;
|
|
44
|
-
hosted?: boolean;
|
|
45
|
-
}): Promise<void>;
|
|
45
|
+
start(opts?: StartOpts): Promise<void>;
|
|
46
46
|
save(opts?: {
|
|
47
47
|
forceFullDump?: boolean;
|
|
48
48
|
}): Promise<void>;
|
package/dist/src/server/index.js
CHANGED
|
@@ -28,6 +28,7 @@ export class DbServer extends DbShared {
|
|
|
28
28
|
modifyDirtyRanges;
|
|
29
29
|
dbCtxExternal; // pointer to zig dbCtx
|
|
30
30
|
migrating = null;
|
|
31
|
+
saveInProgress = false;
|
|
31
32
|
fileSystemPath;
|
|
32
33
|
merkleTree;
|
|
33
34
|
dirtyRanges = new Set();
|
|
@@ -41,6 +42,7 @@ export class DbServer extends DbShared {
|
|
|
41
42
|
unlistenExit;
|
|
42
43
|
saveIntervalInSeconds;
|
|
43
44
|
saveInterval;
|
|
45
|
+
delayInMs;
|
|
44
46
|
constructor({ path, debug, saveIntervalInSeconds, }) {
|
|
45
47
|
super();
|
|
46
48
|
this.fileSystemPath = path;
|
|
@@ -9,7 +9,6 @@ import { setToAwake, waitUntilSleeping } from './utils.js';
|
|
|
9
9
|
const __filename = fileURLToPath(import.meta.url);
|
|
10
10
|
const __dirname = dirname(__filename);
|
|
11
11
|
const workerPath = join(__dirname, 'worker.js');
|
|
12
|
-
let migrationCnt = 0;
|
|
13
12
|
const parseTransform = (transform) => {
|
|
14
13
|
const res = {};
|
|
15
14
|
if (typeof transform === 'object' && transform !== null) {
|
|
@@ -37,13 +36,20 @@ export const migrate = async (server, fromSchema, toSchema, transform) => {
|
|
|
37
36
|
server.emit('info', `migration killed something went wrong ${migrationId}`);
|
|
38
37
|
return true;
|
|
39
38
|
}
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
const newMigrationInProgress = server.migrating !== migrationId;
|
|
40
|
+
if (newMigrationInProgress) {
|
|
41
|
+
server.emit('info', `abort migration - migrating: ${server.migrating} abort: ${migrationId}`);
|
|
42
|
+
}
|
|
43
|
+
return newMigrationInProgress;
|
|
42
44
|
};
|
|
43
45
|
const tmpDb = new BasedDb({
|
|
44
46
|
path: null,
|
|
45
47
|
});
|
|
46
|
-
await tmpDb.start({
|
|
48
|
+
await tmpDb.start({
|
|
49
|
+
clean: true,
|
|
50
|
+
delayInMs: server.delayInMs,
|
|
51
|
+
queryThreads: 0,
|
|
52
|
+
});
|
|
47
53
|
if (abort()) {
|
|
48
54
|
await tmpDb.destroy();
|
|
49
55
|
return;
|
package/dist/src/server/save.js
CHANGED
|
@@ -27,95 +27,128 @@ export function save(db, sync = false, forceFullDump = false, skipMigrationCheck
|
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
29
|
if (db.migrating && !skipMigrationCheck) {
|
|
30
|
+
db.emit('info', 'Block save db is migrating');
|
|
30
31
|
return;
|
|
31
32
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (err) {
|
|
36
|
-
console.error(`Save common failed: ${err}`);
|
|
33
|
+
if (db.saveInProgress) {
|
|
34
|
+
db.emit('info', 'Already have a save in progress cancel save');
|
|
35
|
+
return;
|
|
37
36
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
37
|
+
let ts = Date.now();
|
|
38
|
+
db.saveInProgress = true;
|
|
39
|
+
try {
|
|
40
|
+
let err;
|
|
41
|
+
err = native.saveCommon(join(db.fileSystemPath, COMMON_SDB_FILE), db.dbCtxExternal);
|
|
42
|
+
if (err) {
|
|
43
|
+
console.error(`Save common failed: ${err}`);
|
|
44
|
+
// Return ?
|
|
45
|
+
}
|
|
46
|
+
if (forceFullDump) {
|
|
47
|
+
// We just rebuild the whole tree
|
|
48
|
+
initCsmt(db);
|
|
49
|
+
for (const key in db.schemaTypesParsed) {
|
|
50
|
+
const def = db.schemaTypesParsed[key];
|
|
51
|
+
foreachBlock(db, def, (start, end, _hash) => {
|
|
52
|
+
const typeId = def.id;
|
|
53
|
+
const mtKey = makeCsmtKey(typeId, start);
|
|
54
|
+
const hash = new Uint8Array(16);
|
|
55
|
+
const file = saveRange(db, typeId, start, end, hash);
|
|
56
|
+
if (file === null) {
|
|
57
|
+
throw new Error('full dump failed');
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
const data = {
|
|
61
|
+
file,
|
|
62
|
+
typeId,
|
|
63
|
+
start,
|
|
64
|
+
end,
|
|
65
|
+
};
|
|
66
|
+
db.merkleTree.insert(mtKey, hash, data);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
foreachDirtyBlock(db, (mtKey, typeId, start, end) => {
|
|
46
73
|
const hash = new Uint8Array(16);
|
|
47
74
|
const file = saveRange(db, typeId, start, end, hash);
|
|
48
75
|
if (file === null) {
|
|
49
|
-
|
|
76
|
+
// The previous state should remain in the merkle tree for
|
|
77
|
+
// load and sync purposes.
|
|
78
|
+
return;
|
|
50
79
|
}
|
|
51
80
|
else {
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
81
|
+
const oldLeaf = db.merkleTree.search(mtKey);
|
|
82
|
+
// If (file.length === 0) then the range is empty but that's fine,
|
|
83
|
+
// we'll keep them around for now to maintain the order of the tree.
|
|
84
|
+
if (oldLeaf) {
|
|
85
|
+
oldLeaf.data.file = file;
|
|
86
|
+
db.merkleTree.update(mtKey, hash);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
const data = {
|
|
90
|
+
file,
|
|
91
|
+
typeId,
|
|
92
|
+
start,
|
|
93
|
+
end,
|
|
94
|
+
};
|
|
95
|
+
db.merkleTree.insert(mtKey, hash, data);
|
|
96
|
+
}
|
|
59
97
|
}
|
|
60
98
|
});
|
|
61
99
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
oldLeaf.data.file = file;
|
|
78
|
-
db.merkleTree.update(mtKey, hash);
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
const data = {
|
|
82
|
-
file,
|
|
83
|
-
typeId,
|
|
84
|
-
start,
|
|
85
|
-
end,
|
|
86
|
-
};
|
|
87
|
-
db.merkleTree.insert(mtKey, hash, data);
|
|
88
|
-
}
|
|
100
|
+
db.dirtyRanges.clear();
|
|
101
|
+
const types = {};
|
|
102
|
+
const rangeDumps = {};
|
|
103
|
+
for (const key in db.schemaTypesParsed) {
|
|
104
|
+
const { id, lastId, blockCapacity } = db.schemaTypesParsed[key];
|
|
105
|
+
types[id] = { lastId, blockCapacity };
|
|
106
|
+
rangeDumps[id] = [];
|
|
107
|
+
}
|
|
108
|
+
db.merkleTree.visitLeafNodes((leaf) => {
|
|
109
|
+
const [typeId, start] = destructureCsmtKey(leaf.key);
|
|
110
|
+
if (start == specialBlock)
|
|
111
|
+
return; // skip the type specialBlock
|
|
112
|
+
const data = leaf.data;
|
|
113
|
+
if (start != data.start) {
|
|
114
|
+
console.error(`csmtKey start and range start mismatch: ${start} != ${data.start}`);
|
|
89
115
|
}
|
|
116
|
+
rangeDumps[typeId].push({ ...data, hash: bufToHex(leaf.hash) });
|
|
90
117
|
});
|
|
118
|
+
const data = {
|
|
119
|
+
ts,
|
|
120
|
+
types,
|
|
121
|
+
commonDump: COMMON_SDB_FILE,
|
|
122
|
+
rangeDumps,
|
|
123
|
+
hash: bufToHex(db.merkleTree.getRoot()?.hash ?? new Uint8Array(0)),
|
|
124
|
+
};
|
|
125
|
+
const filePath = join(db.fileSystemPath, WRITELOG_FILE);
|
|
126
|
+
const content = JSON.stringify(data);
|
|
127
|
+
db.emit('info', `Save done took ${Date.now() - ts}ms`);
|
|
128
|
+
if (sync) {
|
|
129
|
+
db.saveInProgress = false;
|
|
130
|
+
return writeFileSync(filePath, content);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
return new Promise((resolve, reject) => {
|
|
134
|
+
return writeFile(filePath, content)
|
|
135
|
+
.then((v) => {
|
|
136
|
+
db.saveInProgress = false;
|
|
137
|
+
resolve(v);
|
|
138
|
+
})
|
|
139
|
+
.catch((err) => {
|
|
140
|
+
console.error('Save: writing writeLog failed');
|
|
141
|
+
db.emit('info', `Save: writing writeLog failed ${err.message}`);
|
|
142
|
+
db.saveInProgress = false;
|
|
143
|
+
reject(err);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
}
|
|
91
147
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const { id, lastId, blockCapacity } = db.schemaTypesParsed[key];
|
|
97
|
-
types[id] = { lastId, blockCapacity };
|
|
98
|
-
rangeDumps[id] = [];
|
|
148
|
+
catch (err) {
|
|
149
|
+
db.emit('info', `Save failed ${err.message}`);
|
|
150
|
+
db.saveInProgress = false;
|
|
151
|
+
throw err;
|
|
99
152
|
}
|
|
100
|
-
db.merkleTree.visitLeafNodes((leaf) => {
|
|
101
|
-
const [typeId, start] = destructureCsmtKey(leaf.key);
|
|
102
|
-
if (start == specialBlock)
|
|
103
|
-
return; // skip the type specialBlock
|
|
104
|
-
const data = leaf.data;
|
|
105
|
-
if (start != data.start) {
|
|
106
|
-
console.error(`csmtKey start and range start mismatch: ${start} != ${data.start}`);
|
|
107
|
-
}
|
|
108
|
-
rangeDumps[typeId].push({ ...data, hash: bufToHex(leaf.hash) });
|
|
109
|
-
});
|
|
110
|
-
const data = {
|
|
111
|
-
ts,
|
|
112
|
-
types,
|
|
113
|
-
commonDump: COMMON_SDB_FILE,
|
|
114
|
-
rangeDumps,
|
|
115
|
-
hash: bufToHex(db.merkleTree.getRoot()?.hash ?? new Uint8Array(0)),
|
|
116
|
-
};
|
|
117
|
-
const filePath = join(db.fileSystemPath, WRITELOG_FILE);
|
|
118
|
-
const content = JSON.stringify(data);
|
|
119
|
-
return sync ? writeFileSync(filePath, content) : writeFile(filePath, content);
|
|
120
153
|
}
|
|
121
154
|
//# sourceMappingURL=save.js.map
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { DbServer } from './index.js';
|
|
2
|
-
export
|
|
2
|
+
export type StartOpts = {
|
|
3
3
|
clean?: boolean;
|
|
4
4
|
hosted?: boolean;
|
|
5
|
-
|
|
5
|
+
delayInMs?: number;
|
|
6
|
+
queryThreads?: number;
|
|
7
|
+
};
|
|
8
|
+
export declare function start(db: DbServer, opts: StartOpts): Promise<void>;
|
package/dist/src/server/start.js
CHANGED
|
@@ -7,7 +7,7 @@ import { availableParallelism } from 'node:os';
|
|
|
7
7
|
import exitHook from 'exit-hook';
|
|
8
8
|
import { save } from './save.js';
|
|
9
9
|
import { DEFAULT_BLOCK_CAPACITY } from '@based/schema/def';
|
|
10
|
-
import { bufToHex } from '@saulx/utils';
|
|
10
|
+
import { bufToHex, wait } from '@saulx/utils';
|
|
11
11
|
import { SCHEMA_FILE, WRITELOG_FILE } from '../types.js';
|
|
12
12
|
import { setSchemaOnServer } from './schema.js';
|
|
13
13
|
export async function start(db, opts) {
|
|
@@ -46,9 +46,8 @@ export async function start(db, opts) {
|
|
|
46
46
|
}
|
|
47
47
|
const schema = await readFile(join(path, SCHEMA_FILE));
|
|
48
48
|
if (schema) {
|
|
49
|
-
|
|
50
|
-
setSchemaOnServer(db,
|
|
51
|
-
// setNativeSchema might still be nessecary...
|
|
49
|
+
const s = JSON.parse(schema.toString());
|
|
50
|
+
setSchemaOnServer(db, s);
|
|
52
51
|
}
|
|
53
52
|
}
|
|
54
53
|
catch (err) {
|
|
@@ -58,7 +57,6 @@ export async function start(db, opts) {
|
|
|
58
57
|
for (const key in csmtTypes) {
|
|
59
58
|
const def = csmtTypes[key];
|
|
60
59
|
const [total, lastId] = native.getTypeInfo(def.id, db.dbCtxExternal);
|
|
61
|
-
def.total = total;
|
|
62
60
|
def.lastId = writelog?.types[def.id]?.lastId || lastId;
|
|
63
61
|
def.blockCapacity =
|
|
64
62
|
writelog?.types[def.id]?.blockCapacity || DEFAULT_BLOCK_CAPACITY;
|
|
@@ -100,11 +98,11 @@ export async function start(db, opts) {
|
|
|
100
98
|
}
|
|
101
99
|
}
|
|
102
100
|
// start workers
|
|
103
|
-
|
|
101
|
+
const queryThreads = opts?.queryThreads ?? availableParallelism();
|
|
104
102
|
const address = native.intFromExternal(db.dbCtxExternal);
|
|
105
|
-
db.workers =
|
|
106
|
-
|
|
107
|
-
db.workers
|
|
103
|
+
db.workers = [];
|
|
104
|
+
for (let i = 0; i < queryThreads; i++) {
|
|
105
|
+
db.workers.push(new DbWorker(address, db, i));
|
|
108
106
|
}
|
|
109
107
|
if (!opts?.hosted) {
|
|
110
108
|
db.unlistenExit = exitHook((signal) => {
|
|
@@ -114,12 +112,16 @@ export async function start(db, opts) {
|
|
|
114
112
|
// This is needed because there is no way to set the process signal mask
|
|
115
113
|
// in Node.js.
|
|
116
114
|
signals.forEach((sig) => process.on(sig, blockSig));
|
|
117
|
-
|
|
115
|
+
db.emit('info', `Exiting with signal: ${signal}`);
|
|
118
116
|
save(db, true);
|
|
119
|
-
|
|
117
|
+
db.emit('info', 'Successfully saved.');
|
|
120
118
|
signals.forEach((sig) => process.off(sig, blockSig));
|
|
121
119
|
});
|
|
122
120
|
}
|
|
121
|
+
const d = performance.now();
|
|
122
|
+
await Promise.all(db.workers.map(({ readyPromise }) => readyPromise));
|
|
123
|
+
db.emit('info', `Starting workers took ${d}ms`);
|
|
124
|
+
// use timeout
|
|
123
125
|
if (db.saveIntervalInSeconds > 0) {
|
|
124
126
|
db.saveInterval ??= setInterval(() => {
|
|
125
127
|
save(db);
|
|
@@ -128,5 +130,9 @@ export async function start(db, opts) {
|
|
|
128
130
|
if (db.schema) {
|
|
129
131
|
db.emit('schema', db.schema);
|
|
130
132
|
}
|
|
133
|
+
if (opts?.delayInMs) {
|
|
134
|
+
this.delayInMs = opts.delayInMs;
|
|
135
|
+
await wait(opts.delayInMs);
|
|
136
|
+
}
|
|
131
137
|
}
|
|
132
138
|
//# sourceMappingURL=start.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isMainThread,
|
|
1
|
+
import { isMainThread, parentPort, workerData } from 'node:worker_threads';
|
|
2
2
|
import native from '../native.js';
|
|
3
3
|
if (isMainThread) {
|
|
4
4
|
console.warn('running query worker.ts in mainthread - incorrect');
|
|
@@ -7,7 +7,6 @@ else if (workerData?.isDbWorker) {
|
|
|
7
7
|
let { address, channel } = workerData;
|
|
8
8
|
let dbCtx = native.externalFromInt(address);
|
|
9
9
|
native.workerCtxInit();
|
|
10
|
-
// const transferList = new Array(1)
|
|
11
10
|
const handleMsg = (msg) => {
|
|
12
11
|
try {
|
|
13
12
|
if (typeof msg === 'bigint') {
|
|
@@ -18,7 +17,6 @@ else if (workerData?.isDbWorker) {
|
|
|
18
17
|
}
|
|
19
18
|
else {
|
|
20
19
|
const arrayBuf = native.getQueryBuf(msg, dbCtx);
|
|
21
|
-
// transferList[0] = arrayBuf
|
|
22
20
|
channel.postMessage(arrayBuf, [arrayBuf]);
|
|
23
21
|
}
|
|
24
22
|
}
|
|
@@ -27,10 +25,7 @@ else if (workerData?.isDbWorker) {
|
|
|
27
25
|
}
|
|
28
26
|
};
|
|
29
27
|
channel.on('message', handleMsg);
|
|
30
|
-
|
|
31
|
-
if (msg) {
|
|
32
|
-
handleMsg(msg.message);
|
|
33
|
-
}
|
|
28
|
+
parentPort.postMessage('READY');
|
|
34
29
|
}
|
|
35
30
|
else {
|
|
36
31
|
console.info('incorrect worker db query');
|
package/dist/src/types.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
export declare const SCHEMA_FILE = "schema.json";
|
|
2
2
|
export declare const WRITELOG_FILE = "writelog.json";
|
|
3
3
|
export declare const COMMON_SDB_FILE = "common.sdb";
|
|
4
|
+
export type BasedDbOpts = {
|
|
5
|
+
path: string;
|
|
6
|
+
maxModifySize?: number;
|
|
7
|
+
debug?: boolean | 'server' | 'client';
|
|
8
|
+
saveIntervalInSeconds?: number;
|
|
9
|
+
};
|