@zukhruf/mutex 0.3.9 → 0.3.11
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/README.md +10 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lock-stores/file-system/file-lock-store.d.ts +4 -0
- package/dist/lock-stores/file-system/file-lock-store.d.ts.map +1 -1
- package/dist/lock-stores/file-system/file-lock-store.js +11 -3
- package/dist/lock-stores/file-system/file-lock-store.js.map +1 -1
- package/dist/lock-stores/file-system/lock-file-store.d.ts +2 -0
- package/dist/lock-stores/file-system/lock-file-store.d.ts.map +1 -1
- package/dist/lock-stores/file-system/lock-file-store.js +7 -11
- package/dist/lock-stores/file-system/lock-file-store.js.map +1 -1
- package/dist/lock-stores/file-system/presence.d.ts +15 -5
- package/dist/lock-stores/file-system/presence.d.ts.map +1 -1
- package/dist/lock-stores/file-system/presence.js +32 -5
- package/dist/lock-stores/file-system/presence.js.map +1 -1
- package/dist/lock-stores/file-system/ticket-queue-file-store.d.ts +2 -0
- package/dist/lock-stores/file-system/ticket-queue-file-store.d.ts.map +1 -1
- package/dist/lock-stores/file-system/ticket-queue-file-store.js +5 -9
- package/dist/lock-stores/file-system/ticket-queue-file-store.js.map +1 -1
- package/dist/lock-stores/ipc/child-process-connection.d.ts +2 -2
- package/dist/lock-stores/ipc/child-process-connection.d.ts.map +1 -1
- package/dist/lock-stores/ipc/child-process-connection.js +2 -2
- package/dist/lock-stores/ipc/child-process-connection.js.map +1 -1
- package/dist/lock-stores/ipc/ipc-lock-coordinator.d.ts +1 -0
- package/dist/lock-stores/ipc/ipc-lock-coordinator.d.ts.map +1 -1
- package/dist/lock-stores/ipc/ipc-lock-coordinator.js +3 -0
- package/dist/lock-stores/ipc/ipc-lock-coordinator.js.map +1 -1
- package/dist/lock-stores/ipc/ipc-store.d.ts +1 -0
- package/dist/lock-stores/ipc/ipc-store.d.ts.map +1 -1
- package/dist/lock-stores/ipc/ipc-store.js +3 -0
- package/dist/lock-stores/ipc/ipc-store.js.map +1 -1
- package/dist/lock-stores/memory/memory-store.d.ts +2 -0
- package/dist/lock-stores/memory/memory-store.d.ts.map +1 -1
- package/dist/lock-stores/memory/memory-store.js +4 -0
- package/dist/lock-stores/memory/memory-store.js.map +1 -1
- package/dist/lock-stores/remote/lock-coordinator.d.ts +4 -2
- package/dist/lock-stores/remote/lock-coordinator.d.ts.map +1 -1
- package/dist/lock-stores/remote/lock-coordinator.js +22 -0
- package/dist/lock-stores/remote/lock-coordinator.js.map +1 -1
- package/dist/lock-stores/remote/protocol.d.ts +26 -0
- package/dist/lock-stores/remote/protocol.d.ts.map +1 -1
- package/dist/lock-stores/remote/protocol.js +18 -0
- package/dist/lock-stores/remote/protocol.js.map +1 -1
- package/dist/lock-stores/remote/queries.d.ts +20 -0
- package/dist/lock-stores/remote/queries.d.ts.map +1 -0
- package/dist/lock-stores/remote/queries.js +57 -0
- package/dist/lock-stores/remote/queries.js.map +1 -0
- package/dist/lock-stores/remote/remote-lock-client.d.ts +1 -0
- package/dist/lock-stores/remote/remote-lock-client.d.ts.map +1 -1
- package/dist/lock-stores/remote/remote-lock-client.js +20 -2
- package/dist/lock-stores/remote/remote-lock-client.js.map +1 -1
- package/dist/lock-stores/remote/unsupported-request-error.d.ts +7 -0
- package/dist/lock-stores/remote/unsupported-request-error.d.ts.map +1 -0
- package/dist/lock-stores/remote/unsupported-request-error.js +12 -0
- package/dist/lock-stores/remote/unsupported-request-error.js.map +1 -0
- package/dist/lock-stores/socket/advertised-ops-connection.d.ts +18 -0
- package/dist/lock-stores/socket/advertised-ops-connection.d.ts.map +1 -0
- package/dist/lock-stores/socket/advertised-ops-connection.js +37 -0
- package/dist/lock-stores/socket/advertised-ops-connection.js.map +1 -0
- package/dist/lock-stores/socket/electing-connector.d.ts.map +1 -1
- package/dist/lock-stores/socket/electing-connector.js +8 -4
- package/dist/lock-stores/socket/electing-connector.js.map +1 -1
- package/dist/lock-stores/socket/handshake.d.ts +6 -2
- package/dist/lock-stores/socket/handshake.d.ts.map +1 -1
- package/dist/lock-stores/socket/handshake.js +13 -4
- package/dist/lock-stores/socket/handshake.js.map +1 -1
- package/dist/lock-stores/socket/lock-server.js +2 -2
- package/dist/lock-stores/socket/lock-server.js.map +1 -1
- package/dist/lock-stores/socket/socket-store.d.ts +1 -0
- package/dist/lock-stores/socket/socket-store.d.ts.map +1 -1
- package/dist/lock-stores/socket/socket-store.js +3 -0
- package/dist/lock-stores/socket/socket-store.js.map +1 -1
- package/dist/lock-stores/sqlite/holder-record.d.ts +18 -0
- package/dist/lock-stores/sqlite/holder-record.d.ts.map +1 -0
- package/dist/lock-stores/sqlite/holder-record.js +85 -0
- package/dist/lock-stores/sqlite/holder-record.js.map +1 -0
- package/dist/lock-stores/sqlite/sqlite-store.d.ts +10 -1
- package/dist/lock-stores/sqlite/sqlite-store.d.ts.map +1 -1
- package/dist/lock-stores/sqlite/sqlite-store.js +40 -7
- package/dist/lock-stores/sqlite/sqlite-store.js.map +1 -1
- package/dist/lock-stores/thread/thread-lock-coordinator.d.ts +1 -0
- package/dist/lock-stores/thread/thread-lock-coordinator.d.ts.map +1 -1
- package/dist/lock-stores/thread/thread-lock-coordinator.js +3 -0
- package/dist/lock-stores/thread/thread-lock-coordinator.js.map +1 -1
- package/dist/lock-stores/thread/thread-store.d.ts +1 -0
- package/dist/lock-stores/thread/thread-store.d.ts.map +1 -1
- package/dist/lock-stores/thread/thread-store.js +3 -0
- package/dist/lock-stores/thread/thread-store.js.map +1 -1
- package/dist/lock-stores/thread/worker-connection.d.ts +2 -2
- package/dist/lock-stores/thread/worker-connection.d.ts.map +1 -1
- package/dist/lock-stores/thread/worker-connection.js +2 -2
- package/dist/lock-stores/thread/worker-connection.js.map +1 -1
- package/dist/mutex/key.d.ts +2 -0
- package/dist/mutex/key.d.ts.map +1 -1
- package/dist/mutex/key.js +4 -0
- package/dist/mutex/key.js.map +1 -1
- package/dist/mutex/lock-store.d.ts +7 -0
- package/dist/mutex/lock-store.d.ts.map +1 -1
- package/dist/mutex/mutex.d.ts +2 -0
- package/dist/mutex/mutex.d.ts.map +1 -1
- package/dist/mutex/mutex.js +4 -0
- package/dist/mutex/mutex.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import { isRecord } from "../../shared/is-record.js";
|
|
2
|
+
import { ADDED_OPS } from "../remote/protocol.js";
|
|
2
3
|
/**
|
|
3
4
|
* The version of the messages a socket store's processes exchange. It changes
|
|
4
5
|
* only when they change, so processes that run different package versions
|
|
5
6
|
* with the same protocol still share a directory. The `hello` and the
|
|
6
7
|
* `refused` answer keep their shape in every version: they are how two
|
|
7
|
-
* versions find out that they differ.
|
|
8
|
+
* versions find out that they differ. A request added later needs no new
|
|
9
|
+
* version: the `welcome` lists it (see `ADDED_OPS`).
|
|
8
10
|
*/
|
|
9
11
|
export const PROTOCOL_VERSION = 1;
|
|
10
12
|
/** Says which protocol this process speaks, and reads the leader's answer. */
|
|
11
13
|
export async function greet(socket) {
|
|
12
14
|
socket.write(`${JSON.stringify({ op: 'hello', version: PROTOCOL_VERSION })}\n`);
|
|
13
15
|
const answer = parse(await readLine(socket));
|
|
14
|
-
if (isRecord(answer) && answer.op === 'welcome')
|
|
15
|
-
return { kind: 'welcome' };
|
|
16
|
+
if (isRecord(answer) && answer.op === 'welcome') {
|
|
17
|
+
return { kind: 'welcome', ops: listedOps(answer.ops) };
|
|
18
|
+
}
|
|
16
19
|
if (isRecord(answer) &&
|
|
17
20
|
answer.op === 'refused' &&
|
|
18
21
|
typeof answer.version === 'number') {
|
|
@@ -36,13 +39,19 @@ export async function welcome(socket) {
|
|
|
36
39
|
return false;
|
|
37
40
|
}
|
|
38
41
|
if (hello.version === PROTOCOL_VERSION) {
|
|
39
|
-
|
|
42
|
+
// A follower of 0.3.x reads only `op`, so the list is new to followers only.
|
|
43
|
+
socket.write(`${JSON.stringify({ op: 'welcome', ops: [...ADDED_OPS] })}\n`);
|
|
40
44
|
return true;
|
|
41
45
|
}
|
|
42
46
|
// Destroyed once the answer is written: a paused socket would never see a silent process hang up.
|
|
43
47
|
socket.end(`${JSON.stringify({ op: 'refused', version: PROTOCOL_VERSION })}\n`, () => socket.destroy());
|
|
44
48
|
return false;
|
|
45
49
|
}
|
|
50
|
+
function listedOps(ops) {
|
|
51
|
+
if (!Array.isArray(ops))
|
|
52
|
+
return new Set();
|
|
53
|
+
return new Set(ops.filter((op) => typeof op === 'string'));
|
|
54
|
+
}
|
|
46
55
|
function parse(line) {
|
|
47
56
|
if (line === undefined)
|
|
48
57
|
return undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handshake.js","sourceRoot":"","sources":["../../../src/lock-stores/socket/handshake.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"handshake.js","sourceRoot":"","sources":["../../../src/lock-stores/socket/handshake.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ import { createServer } from 'node:net';
|
|
|
3
3
|
import { EpochTokenSource } from "../../fencing/epoch-token-source.js";
|
|
4
4
|
import { isErrno } from "../../shared/fs/errno.js";
|
|
5
5
|
import { LockCoordinator } from "../remote/lock-coordinator.js";
|
|
6
|
-
import {
|
|
6
|
+
import { isRequestEnvelope, } from "../remote/protocol.js";
|
|
7
7
|
import { welcome } from "./handshake.js";
|
|
8
8
|
import { SocketConnection } from "./socket-connection.js";
|
|
9
9
|
/**
|
|
@@ -42,7 +42,7 @@ export class LockServer {
|
|
|
42
42
|
void welcome(socket).then((speaksOurs) => {
|
|
43
43
|
if (!speaksOurs)
|
|
44
44
|
return;
|
|
45
|
-
coordinator.serve(new SocketConnection(socket,
|
|
45
|
+
coordinator.serve(new SocketConnection(socket, isRequestEnvelope));
|
|
46
46
|
});
|
|
47
47
|
});
|
|
48
48
|
await new Promise((resolve, reject) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lock-server.js","sourceRoot":"","sources":["../../../src/lock-stores/socket/lock-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAA4B,YAAY,EAAE,MAAM,UAAU,CAAC;AAElE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAEvE,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAGL,
|
|
1
|
+
{"version":3,"file":"lock-server.js","sourceRoot":"","sources":["../../../src/lock-stores/socket/lock-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -28,6 +28,7 @@ export declare class SocketStore extends EventEmitter<{
|
|
|
28
28
|
constructor(directory: string, { pollInterval, graceWindow }?: SocketStoreOptions);
|
|
29
29
|
acquire(key: string, options?: AcquireOptions): Promise<LockHandle>;
|
|
30
30
|
tryAcquire(key: string): Promise<LockHandle | undefined>;
|
|
31
|
+
isHeld(key: string): Promise<boolean>;
|
|
31
32
|
/** Stops a campaign still in progress first, so no lock server starts after disposal. */
|
|
32
33
|
[Symbol.asyncDispose](): Promise<void>;
|
|
33
34
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socket-store.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/socket/socket-store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAU3E,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE/C,MAAM,WAAW,kBAAkB;IACjC,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;GASG;AACH,qBAAa,WACX,SAAQ,YAAY,CAAC;IAAE,IAAI,EAAE,CAAC,UAAU,CAAC,CAAA;CAAE,CAC3C,YAAW,SAAS,EAAE,eAAe;;gBAOnC,SAAS,EAAE,MAAM,EACjB,EAAE,YAAiB,EAAE,WAAiB,EAAE,GAAE,kBAAuB;IAgCnE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;IAInE,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAIxD,yFAAyF;IACnF,CAAC,MAAM,CAAC,YAAY,CAAC;CAI5B"}
|
|
1
|
+
{"version":3,"file":"socket-store.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/socket/socket-store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAU3E,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE/C,MAAM,WAAW,kBAAkB;IACjC,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;GASG;AACH,qBAAa,WACX,SAAQ,YAAY,CAAC;IAAE,IAAI,EAAE,CAAC,UAAU,CAAC,CAAA;CAAE,CAC3C,YAAW,SAAS,EAAE,eAAe;;gBAOnC,SAAS,EAAE,MAAM,EACjB,EAAE,YAAiB,EAAE,WAAiB,EAAE,GAAE,kBAAuB;IAgCnE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;IAInE,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAIxD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIrC,yFAAyF;IACnF,CAAC,MAAM,CAAC,YAAY,CAAC;CAI5B"}
|
|
@@ -49,6 +49,9 @@ export class SocketStore extends EventEmitter {
|
|
|
49
49
|
tryAcquire(key) {
|
|
50
50
|
return this.#client.tryAcquire(key);
|
|
51
51
|
}
|
|
52
|
+
isHeld(key) {
|
|
53
|
+
return this.#client.isHeld(key);
|
|
54
|
+
}
|
|
52
55
|
/** Stops a campaign still in progress first, so no lock server starts after disposal. */
|
|
53
56
|
async [Symbol.asyncDispose]() {
|
|
54
57
|
await this.#client.close();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socket-store.js","sourceRoot":"","sources":["../../../src/lock-stores/socket/socket-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAG1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,8EAA8E;AAC9E,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAc9B;;;;;;;;;GASG;AACH,MAAM,OAAO,WACX,SAAQ,YAAoC;IAGnC,OAAO,CAAmB;IACnC,8EAA8E;IACrE,QAAQ,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE/C,YACE,SAAiB,EACjB,EAAE,YAAY,GAAG,EAAE,EAAE,WAAW,GAAG,GAAG,KAAyB,EAAE;QAEjE,KAAK,EAAE,CAAC;QACR,MAAM,UAAU,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,GAAG,IAAI,gBAAgB,CACjC,IAAI,oBAAoB,CACtB,IAAI,uBAAuB,CACzB,SAAS,EACT,IAAI,iBAAiB,CAAC;YACpB,UAAU;YACV,QAAQ,EAAE,IAAI,cAAc,CAAC,SAAS,EAAE,EAAE,YAAY,EAAE,CAAC;YACzD,YAAY;YACZ,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;gBAC1B,oGAAoG;gBACpG,YAAY,QAAQ,GAAG,IAAI,oBAAoB,EAAE,CAAC;gBAClD,QAAQ,CAAC,KAAK,CACZ,MAAM,UAAU,CAAC,KAAK,CAAC,UAAU,EAAE,UAAU,EAAE;oBAC7C,gEAAgE;oBAChE,WAAW,EAAE,UAAU,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;iBACrD,CAAC,EACF,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAC7B,CAAC;gBACF,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;gBAC5B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;YACrC,CAAC;YACD,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC;SAC/C,CAAC,CACH,CACF,CACF,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,GAAW,EAAE,OAAwB;QAC3C,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,UAAU,CAAC,GAAW;QACpB,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC;IAED,yFAAyF;IACzF,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC;QACzB,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC3B,MAAM,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC;IACrC,CAAC;CACF;AAED;;;;GAIG;AACH,SAAS,aAAa,CAAC,SAAiB;IACtC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,MAAM,EAAE,GAAG,UAAU,CAAC,QAAQ,CAAC;aAC5B,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;aACxC,MAAM,CAAC,KAAK,CAAC;aACb,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAChB,OAAO,sBAAsB,EAAE,EAAE,CAAC;IACpC,CAAC;IACD,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAChD,IAAI,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,iBAAiB,EAAE,CAAC;QACtD,MAAM,IAAI,UAAU,CAClB,mBAAmB,UAAU,YAAY,iBAAiB,qCAAqC,CAChG,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
|
1
|
+
{"version":3,"file":"socket-store.js","sourceRoot":"","sources":["../../../src/lock-stores/socket/socket-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Names the holder of a SQLite lock in `<lock>.holder/caller`, beside the
|
|
3
|
+
* holder's presence. A look reads these two files and never the lock that
|
|
4
|
+
* callers wait for, so it never makes one of them busy. Only the holder of
|
|
5
|
+
* the lock writes in the folder, so nobody else ever competes for its files.
|
|
6
|
+
*/
|
|
7
|
+
export declare class HolderRecord {
|
|
8
|
+
#private;
|
|
9
|
+
constructor(lockPath: string);
|
|
10
|
+
/**
|
|
11
|
+
* Names this caller as the holder: its presence first, then the record that
|
|
12
|
+
* names it, so a look never finds a record whose presence is still to come.
|
|
13
|
+
*/
|
|
14
|
+
announce(): Promise<AsyncDisposable>;
|
|
15
|
+
/** Whether the holder that the record names still runs. Writes nothing. */
|
|
16
|
+
isPresent(): Promise<boolean>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=holder-record.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"holder-record.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/sqlite/holder-record.ts"],"names":[],"mappings":"AAUA;;;;;GAKG;AACH,qBAAa,YAAY;;gBAIX,QAAQ,EAAE,MAAM;IAK5B;;;OAGG;IACG,QAAQ,IAAI,OAAO,CAAC,eAAe,CAAC;IAiB1C,2EAA2E;IAC3E,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;CAyC9B"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { mkdir, readdir, unlink } from 'node:fs/promises';
|
|
3
|
+
import { basename, join } from 'node:path';
|
|
4
|
+
import { atomicWrite } from "../../shared/fs/atomic-write.js";
|
|
5
|
+
import { isErrno } from "../../shared/fs/errno.js";
|
|
6
|
+
import { patiently } from "../../shared/fs/patiently.js";
|
|
7
|
+
import { Caller } from "../file-system/caller.js";
|
|
8
|
+
import { Presence } from "../file-system/presence.js";
|
|
9
|
+
/**
|
|
10
|
+
* Names the holder of a SQLite lock in `<lock>.holder/caller`, beside the
|
|
11
|
+
* holder's presence. A look reads these two files and never the lock that
|
|
12
|
+
* callers wait for, so it never makes one of them busy. Only the holder of
|
|
13
|
+
* the lock writes in the folder, so nobody else ever competes for its files.
|
|
14
|
+
*/
|
|
15
|
+
export class HolderRecord {
|
|
16
|
+
#folder;
|
|
17
|
+
#path;
|
|
18
|
+
constructor(lockPath) {
|
|
19
|
+
this.#folder = `${lockPath}.holder`;
|
|
20
|
+
this.#path = join(this.#folder, 'caller');
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Names this caller as the holder: its presence first, then the record that
|
|
24
|
+
* names it, so a look never finds a record whose presence is still to come.
|
|
25
|
+
*/
|
|
26
|
+
async announce() {
|
|
27
|
+
const me = Caller.current();
|
|
28
|
+
await mkdir(this.#folder, { recursive: true });
|
|
29
|
+
const presence = Presence.claim(Presence.pathOf(this.#path, me));
|
|
30
|
+
try {
|
|
31
|
+
await atomicWrite(this.#path, me.serialize());
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
await presence.withdraw();
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
|
+
await this.#clearEarlierHolders(me);
|
|
38
|
+
return {
|
|
39
|
+
[Symbol.asyncDispose]: () => presence.releaseAfter(() => patiently(() => unlink(this.#path))),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/** Whether the holder that the record names still runs. Writes nothing. */
|
|
43
|
+
isPresent() {
|
|
44
|
+
return Presence.isNamedCallerPresent(this.#path, () => this.#read());
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Every other file in the folder was left by an earlier holder that stopped
|
|
48
|
+
* before it removed its own. Such a file locks nothing, so a delete that
|
|
49
|
+
* fails leaves it for the next holder and never fails this grant.
|
|
50
|
+
*/
|
|
51
|
+
async #clearEarlierHolders(me) {
|
|
52
|
+
const mine = new Set([
|
|
53
|
+
basename(this.#path),
|
|
54
|
+
basename(Presence.pathOf(this.#path, me)),
|
|
55
|
+
]);
|
|
56
|
+
const names = await readdir(this.#folder).catch(() => []);
|
|
57
|
+
await Promise.all(names
|
|
58
|
+
.filter((name) => !mine.has(name))
|
|
59
|
+
.map((name) => unlink(join(this.#folder, name)).catch(() => { })));
|
|
60
|
+
}
|
|
61
|
+
async #read() {
|
|
62
|
+
let content;
|
|
63
|
+
try {
|
|
64
|
+
// A synchronous read opens and closes the file in one call, so Windows
|
|
65
|
+
// can still replace the record while looks read it.
|
|
66
|
+
content = await patiently(async () => readFileSync(this.#path, 'utf8'));
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
if (isErrno(error, 'ENOENT'))
|
|
70
|
+
return undefined;
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
return Caller.parse(content);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
// The record is replaced in one step, so only a machine that stopped
|
|
78
|
+
// mid-write leaves one that cannot be read, and it names nobody who runs.
|
|
79
|
+
if (error instanceof SyntaxError)
|
|
80
|
+
return undefined;
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=holder-record.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"holder-record.js","sourceRoot":"","sources":["../../../src/lock-stores/sqlite/holder-record.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,17 +7,26 @@ import { FileLockStore } from '../file-system/file-lock-store.ts';
|
|
|
7
7
|
* crash never leaves a key locked. Keep the default rollback journal: in WAL
|
|
8
8
|
* mode an exclusive transaction no longer blocks readers.
|
|
9
9
|
*
|
|
10
|
+
* Even a read of that file makes it busy for a caller that tries to take it,
|
|
11
|
+
* so the holder also names itself in a holder record, which a look reads
|
|
12
|
+
* instead.
|
|
13
|
+
*
|
|
10
14
|
* Callers in this process first line up in a queue in memory, so only the
|
|
11
15
|
* first one opens a database connection: one open file per key per process,
|
|
12
16
|
* however many callers wait, and first-come order within the process.
|
|
13
17
|
*/
|
|
14
18
|
export declare class SqliteStore extends FileLockStore {
|
|
15
19
|
#private;
|
|
16
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* SQLite keeps the rollback journal of a key's database at `<path>-journal`.
|
|
22
|
+
* The holder folder `<path>.holder` is shorter, so a key keeps the file name
|
|
23
|
+
* that versions without the folder gave it.
|
|
24
|
+
*/
|
|
17
25
|
protected readonly longestSuffix: number;
|
|
18
26
|
acquire(key: string, options?: AcquireOptions): Promise<LockHandle>;
|
|
19
27
|
tryAcquire(key: string): Promise<LockHandle | undefined>;
|
|
20
28
|
protected lock(path: string, signal: AbortSignal | undefined): Promise<AsyncDisposable>;
|
|
21
29
|
protected tryLock(path: string): Promise<AsyncDisposable | undefined>;
|
|
30
|
+
protected isHeldAt(path: string): Promise<boolean>;
|
|
22
31
|
}
|
|
23
32
|
//# sourceMappingURL=sqlite-store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-store.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/sqlite/sqlite-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"sqlite-store.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/sqlite/sqlite-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAIlE;;;;;;;;;;;;;GAaG;AACH,qBAAa,WAAY,SAAQ,aAAa;;IAC5C;;;;OAIG;IACH,SAAS,CAAC,QAAQ,CAAC,aAAa,SAAqB;IAGtC,OAAO,CACpB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,UAAU,CAAC;IAWP,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;cAcvD,IAAI,CAClB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,WAAW,GAAG,SAAS,GAC9B,OAAO,CAAC,eAAe,CAAC;cAaX,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAc3E,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAGnD"}
|
|
@@ -2,18 +2,27 @@ import { DatabaseSync } from 'node:sqlite';
|
|
|
2
2
|
import { isBusy } from "../../shared/sqlite/is-busy.js";
|
|
3
3
|
import { FileLockStore } from "../file-system/file-lock-store.js";
|
|
4
4
|
import { MemoryStore } from "../memory/memory-store.js";
|
|
5
|
+
import { HolderRecord } from "./holder-record.js";
|
|
5
6
|
/**
|
|
6
7
|
* Holds an exclusive SQLite transaction on the key's database file. SQLite
|
|
7
8
|
* locks through the kernel, which releases them when the holder dies, so a
|
|
8
9
|
* crash never leaves a key locked. Keep the default rollback journal: in WAL
|
|
9
10
|
* mode an exclusive transaction no longer blocks readers.
|
|
10
11
|
*
|
|
12
|
+
* Even a read of that file makes it busy for a caller that tries to take it,
|
|
13
|
+
* so the holder also names itself in a holder record, which a look reads
|
|
14
|
+
* instead.
|
|
15
|
+
*
|
|
11
16
|
* Callers in this process first line up in a queue in memory, so only the
|
|
12
17
|
* first one opens a database connection: one open file per key per process,
|
|
13
18
|
* however many callers wait, and first-come order within the process.
|
|
14
19
|
*/
|
|
15
20
|
export class SqliteStore extends FileLockStore {
|
|
16
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* SQLite keeps the rollback journal of a key's database at `<path>-journal`.
|
|
23
|
+
* The holder folder `<path>.holder` is shorter, so a key keeps the file name
|
|
24
|
+
* that versions without the folder gave it.
|
|
25
|
+
*/
|
|
17
26
|
longestSuffix = '-journal'.length;
|
|
18
27
|
#inProcess = new MemoryStore();
|
|
19
28
|
async acquire(key, options = {}) {
|
|
@@ -54,21 +63,26 @@ export class SqliteStore extends FileLockStore {
|
|
|
54
63
|
database.close();
|
|
55
64
|
throw error;
|
|
56
65
|
}
|
|
57
|
-
return holding(database);
|
|
66
|
+
return holding(path, database);
|
|
58
67
|
}
|
|
59
68
|
async tryLock(path) {
|
|
60
69
|
const database = new DatabaseSync(path, { timeout: 0 });
|
|
70
|
+
let begun;
|
|
61
71
|
try {
|
|
62
|
-
|
|
63
|
-
return holding(database);
|
|
72
|
+
begun = begin(database);
|
|
64
73
|
}
|
|
65
74
|
catch (error) {
|
|
66
75
|
database.close();
|
|
67
76
|
throw error;
|
|
68
77
|
}
|
|
78
|
+
if (begun)
|
|
79
|
+
return holding(path, database);
|
|
69
80
|
database.close();
|
|
70
81
|
return undefined;
|
|
71
82
|
}
|
|
83
|
+
isHeldAt(path) {
|
|
84
|
+
return new HolderRecord(path).isPresent();
|
|
85
|
+
}
|
|
72
86
|
}
|
|
73
87
|
/** Starts the exclusive transaction, or reports that another connection holds it. */
|
|
74
88
|
function begin(database) {
|
|
@@ -82,14 +96,33 @@ function begin(database) {
|
|
|
82
96
|
throw error;
|
|
83
97
|
}
|
|
84
98
|
}
|
|
85
|
-
|
|
99
|
+
/** Names the holder of the transaction. The transaction ends however that, or the release of the record, goes. */
|
|
100
|
+
async function holding(path, database) {
|
|
101
|
+
const record = await new HolderRecord(path)
|
|
102
|
+
.announce()
|
|
103
|
+
.catch((error) => {
|
|
104
|
+
unlock(database);
|
|
105
|
+
throw error;
|
|
106
|
+
});
|
|
86
107
|
return {
|
|
87
108
|
[Symbol.asyncDispose]: async () => {
|
|
88
|
-
|
|
89
|
-
|
|
109
|
+
try {
|
|
110
|
+
await record[Symbol.asyncDispose]();
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
unlock(database);
|
|
114
|
+
}
|
|
90
115
|
},
|
|
91
116
|
};
|
|
92
117
|
}
|
|
118
|
+
function unlock(database) {
|
|
119
|
+
try {
|
|
120
|
+
database.exec('ROLLBACK');
|
|
121
|
+
}
|
|
122
|
+
finally {
|
|
123
|
+
database.close();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
93
126
|
/** Releases the database lock first, then lets the next caller in this process try. */
|
|
94
127
|
function withTurn(handle, turn) {
|
|
95
128
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-store.js","sourceRoot":"","sources":["../../../src/lock-stores/sqlite/sqlite-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,OAAO,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"sqlite-store.js","sourceRoot":"","sources":["../../../src/lock-stores/sqlite/sqlite-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,7 @@ export declare class ThreadLockCoordinator implements LockStore {
|
|
|
16
16
|
constructor({ tokens, }?: ThreadLockCoordinatorOptions);
|
|
17
17
|
acquire(key: string, options?: AcquireOptions): Promise<LockHandle>;
|
|
18
18
|
tryAcquire(key: string): Promise<LockHandle | undefined>;
|
|
19
|
+
isHeld(key: string): Promise<boolean>;
|
|
19
20
|
/** Serves `worker`. When the thread stops, everything it held or waited for is released. */
|
|
20
21
|
adopt(worker: Worker): void;
|
|
21
22
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread-lock-coordinator.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/thread/thread-lock-coordinator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAI3E,MAAM,WAAW,4BAA4B;IAC3C,6EAA6E;IAC7E,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;GAIG;AACH,qBAAa,qBAAsB,YAAW,SAAS;;gBAGzC,EACV,MAAiC,GAClC,GAAE,4BAAiC;IAIpC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;IAInE,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAIxD,4FAA4F;IAC5F,KAAK,CAAC,MAAM,EAAE,MAAM;CAGrB"}
|
|
1
|
+
{"version":3,"file":"thread-lock-coordinator.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/thread/thread-lock-coordinator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAI3E,MAAM,WAAW,4BAA4B;IAC3C,6EAA6E;IAC7E,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;GAIG;AACH,qBAAa,qBAAsB,YAAW,SAAS;;gBAGzC,EACV,MAAiC,GAClC,GAAE,4BAAiC;IAIpC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;IAInE,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAIxD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIrC,4FAA4F;IAC5F,KAAK,CAAC,MAAM,EAAE,MAAM;CAGrB"}
|
|
@@ -17,6 +17,9 @@ export class ThreadLockCoordinator {
|
|
|
17
17
|
tryAcquire(key) {
|
|
18
18
|
return this.#coordinator.tryAcquire(key);
|
|
19
19
|
}
|
|
20
|
+
isHeld(key) {
|
|
21
|
+
return this.#coordinator.isHeld(key);
|
|
22
|
+
}
|
|
20
23
|
/** Serves `worker`. When the thread stops, everything it held or waited for is released. */
|
|
21
24
|
adopt(worker) {
|
|
22
25
|
this.#coordinator.serve(new WorkerConnection(worker));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread-lock-coordinator.js","sourceRoot":"","sources":["../../../src/lock-stores/thread/thread-lock-coordinator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAI3E,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAO1D;;;;GAIG;AACH,MAAM,OAAO,qBAAqB;IACvB,YAAY,CAAkB;IAEvC,YAAY,EACV,MAAM,GAAG,IAAI,kBAAkB,EAAE,MACD,EAAE;QAClC,IAAI,CAAC,YAAY,GAAG,IAAI,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,CAAC,GAAW,EAAE,OAAwB;QAC3C,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAED,UAAU,CAAC,GAAW;QACpB,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC3C,CAAC;IAED,4FAA4F;IAC5F,KAAK,CAAC,MAAc;QAClB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;IACxD,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"thread-lock-coordinator.js","sourceRoot":"","sources":["../../../src/lock-stores/thread/thread-lock-coordinator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAI3E,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAO1D;;;;GAIG;AACH,MAAM,OAAO,qBAAqB;IACvB,YAAY,CAAkB;IAEvC,YAAY,EACV,MAAM,GAAG,IAAI,kBAAkB,EAAE,MACD,EAAE;QAClC,IAAI,CAAC,YAAY,GAAG,IAAI,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,CAAC,GAAW,EAAE,OAAwB;QAC3C,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAED,UAAU,CAAC,GAAW;QACpB,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACvC,CAAC;IAED,4FAA4F;IAC5F,KAAK,CAAC,MAAc;QAClB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;IACxD,CAAC;CACF"}
|
|
@@ -9,5 +9,6 @@ export declare class ThreadStore implements LockStore {
|
|
|
9
9
|
constructor();
|
|
10
10
|
acquire(key: string, options?: AcquireOptions): Promise<LockHandle>;
|
|
11
11
|
tryAcquire(key: string): Promise<LockHandle | undefined>;
|
|
12
|
+
isHeld(key: string): Promise<boolean>;
|
|
12
13
|
}
|
|
13
14
|
//# sourceMappingURL=thread-store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread-store.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/thread/thread-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAmB3E;;;GAGG;AACH,qBAAa,WAAY,YAAW,SAAS;;;IAc3C,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;IAInE,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"thread-store.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/thread/thread-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAmB3E;;;GAGG;AACH,qBAAa,WAAY,YAAW,SAAS;;;IAc3C,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;IAInE,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAIxD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAGtC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread-store.js","sourceRoot":"","sources":["../../../src/lock-stores/thread/thread-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAInE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAE1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAEnE,qEAAqE;AACrE,MAAM,mBAAmB;IACd,WAAW,CAA4C;IAEhE,YAAY,IAAiB;QAC3B,IAAI,CAAC,WAAW,GAAG,CAAC,IAAI,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC/D,CAAC;IAED,KAAK,CAAC,OAAO;QACX,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;IACvC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,WAAW;IACb,OAAO,CAAmB;IAEnC;QACE,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CACb,uGAAuG,CACxG,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,gBAAgB,CACjC,IAAI,oBAAoB,CAAC,IAAI,mBAAmB,CAAC,UAAU,CAAC,CAAC,CAC9D,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,GAAW,EAAE,OAAwB;QAC3C,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,UAAU,CAAC,GAAW;QACpB,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"thread-store.js","sourceRoot":"","sources":["../../../src/lock-stores/thread/thread-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAInE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAE1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAEnE,qEAAqE;AACrE,MAAM,mBAAmB;IACd,WAAW,CAA4C;IAEhE,YAAY,IAAiB;QAC3B,IAAI,CAAC,WAAW,GAAG,CAAC,IAAI,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC/D,CAAC;IAED,KAAK,CAAC,OAAO;QACX,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;IACvC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,WAAW;IACb,OAAO,CAAmB;IAEnC;QACE,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CACb,uGAAuG,CACxG,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,gBAAgB,CACjC,IAAI,oBAAoB,CAAC,IAAI,mBAAmB,CAAC,UAAU,CAAC,CAAC,CAC9D,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,GAAW,EAAE,OAAwB;QAC3C,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,UAAU,CAAC,GAAW;QACpB,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;CACF"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { EventEmitter } from 'node:events';
|
|
2
2
|
import type { Worker } from 'node:worker_threads';
|
|
3
3
|
import type { Connection, ConnectionEvents } from '../remote/connection.ts';
|
|
4
|
-
import { type
|
|
4
|
+
import { type LockResponse, type RequestEnvelope } from '../remote/protocol.ts';
|
|
5
5
|
/**
|
|
6
6
|
* The coordinator's end of the message port to one worker thread. `Worker`
|
|
7
7
|
* emits `exit` however the thread stops, so a terminated or crashed holder
|
|
8
8
|
* is always noticed.
|
|
9
9
|
*/
|
|
10
|
-
export declare class WorkerConnection extends EventEmitter<ConnectionEvents<
|
|
10
|
+
export declare class WorkerConnection extends EventEmitter<ConnectionEvents<RequestEnvelope>> implements Connection<LockResponse, RequestEnvelope> {
|
|
11
11
|
#private;
|
|
12
12
|
constructor(worker: Worker);
|
|
13
13
|
send(response: LockResponse): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-connection.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/thread/worker-connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAElD,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE5E,OAAO,EACL,KAAK,
|
|
1
|
+
{"version":3,"file":"worker-connection.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/thread/worker-connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAElD,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE5E,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,eAAe,EAErB,MAAM,uBAAuB,CAAC;AAE/B;;;;GAIG;AACH,qBAAa,gBACX,SAAQ,YAAY,CAAC,gBAAgB,CAAC,eAAe,CAAC,CACtD,YAAW,UAAU,CAAC,YAAY,EAAE,eAAe,CAAC;;gBAcxC,MAAM,EAAE,MAAM;IAOpB,IAAI,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAQjD,kEAAkE;IAClE,GAAG;IAEH,KAAK;IAEL,KAAK;CAIN"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { EventEmitter } from 'node:events';
|
|
2
2
|
import { unwrap, wrap } from "../remote/envelope.js";
|
|
3
|
-
import {
|
|
3
|
+
import { isRequestEnvelope, } from "../remote/protocol.js";
|
|
4
4
|
/**
|
|
5
5
|
* The coordinator's end of the message port to one worker thread. `Worker`
|
|
6
6
|
* emits `exit` however the thread stops, so a terminated or crashed holder
|
|
@@ -10,7 +10,7 @@ export class WorkerConnection extends EventEmitter {
|
|
|
10
10
|
#worker;
|
|
11
11
|
#onMessage = (envelope) => {
|
|
12
12
|
const request = unwrap(envelope);
|
|
13
|
-
if (
|
|
13
|
+
if (isRequestEnvelope(request))
|
|
14
14
|
this.emit('message', request);
|
|
15
15
|
};
|
|
16
16
|
#onExit = () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-connection.js","sourceRoot":"","sources":["../../../src/lock-stores/thread/worker-connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAGL,
|
|
1
|
+
{"version":3,"file":"worker-connection.js","sourceRoot":"","sources":["../../../src/lock-stores/thread/worker-connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAGL,iBAAiB,GAClB,MAAM,uBAAuB,CAAC;AAE/B;;;;GAIG;AACH,MAAM,OAAO,gBACX,SAAQ,YAA+C;IAG9C,OAAO,CAAS;IAEhB,UAAU,GAAG,CAAC,QAAiB,EAAE,EAAE;QAC1C,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;QACjC,IAAI,iBAAiB,CAAC,OAAO,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAChE,CAAC,CAAC;IAEO,OAAO,GAAG,GAAG,EAAE;QACtB,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC,CAAC;IAEF,YAAY,MAAc;QACxB,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACtC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,QAAsB;QAC/B,sFAAsF;QACtF,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,kEAAkE;IAClE,GAAG,KAAI,CAAC;IAER,KAAK,KAAI,CAAC;IAEV,KAAK;QACH,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACzC,CAAC;CACF"}
|
package/dist/mutex/key.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export declare class Key<O extends Outcome> {
|
|
|
11
11
|
#private;
|
|
12
12
|
readonly name: string;
|
|
13
13
|
constructor(mutex: Mutex, name: string, mode: AcquireMode<O>);
|
|
14
|
+
/** Whether the key has a holder now, learned without acquiring it. The holder can change before the answer arrives. */
|
|
15
|
+
isHeld(): Promise<boolean>;
|
|
14
16
|
/** Runs `task` with the key's own acquire mode. */
|
|
15
17
|
run<T>(task: (lease: Lease) => Promise<T>, options?: AcquireOptions & {
|
|
16
18
|
mode?: undefined;
|
package/dist/mutex/key.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"key.d.ts","sourceRoot":"","sources":["../../src/mutex/key.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC;;;;GAIG;AACH,qBAAa,GAAG,CAAC,CAAC,SAAS,OAAO;;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAIV,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;IAM5D,mDAAmD;IACnD,GAAG,CAAC,CAAC,EACH,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,EAClC,OAAO,CAAC,EAAE,cAAc,GAAG;QAAE,IAAI,CAAC,EAAE,SAAS,CAAA;KAAE,GAC9C,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChC,qEAAqE;IACrE,GAAG,CAAC,CAAC,EAAE,CAAC,SAAS,OAAO,EACtB,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,EAClC,OAAO,EAAE,cAAc,GAAG;QAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAA;KAAE,GACjD,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAYjC"}
|
|
1
|
+
{"version":3,"file":"key.d.ts","sourceRoot":"","sources":["../../src/mutex/key.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC;;;;GAIG;AACH,qBAAa,GAAG,CAAC,CAAC,SAAS,OAAO;;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAIV,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;IAM5D,uHAAuH;IACvH,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAI1B,mDAAmD;IACnD,GAAG,CAAC,CAAC,EACH,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,EAClC,OAAO,CAAC,EAAE,cAAc,GAAG;QAAE,IAAI,CAAC,EAAE,SAAS,CAAA;KAAE,GAC9C,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChC,qEAAqE;IACrE,GAAG,CAAC,CAAC,EAAE,CAAC,SAAS,OAAO,EACtB,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,EAClC,OAAO,EAAE,cAAc,GAAG;QAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAA;KAAE,GACjD,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAYjC"}
|
package/dist/mutex/key.js
CHANGED
|
@@ -12,6 +12,10 @@ export class Key {
|
|
|
12
12
|
this.name = name;
|
|
13
13
|
this.#mode = mode;
|
|
14
14
|
}
|
|
15
|
+
/** Whether the key has a holder now, learned without acquiring it. The holder can change before the answer arrives. */
|
|
16
|
+
isHeld() {
|
|
17
|
+
return this.#mutex.isHeld(this.name);
|
|
18
|
+
}
|
|
15
19
|
run(task, { mode, signal, } = {}) {
|
|
16
20
|
return mode === undefined
|
|
17
21
|
? this.#mutex.acquire(this.name, task, { mode: this.#mode, signal })
|
package/dist/mutex/key.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"key.js","sourceRoot":"","sources":["../../src/mutex/key.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,MAAM,OAAO,GAAG;IACL,IAAI,CAAS;IACb,MAAM,CAAQ;IACd,KAAK,CAAiB;IAE/B,YAAY,KAAY,EAAE,IAAY,EAAE,IAAoB;QAC1D,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAYD,GAAG,CACD,IAAkC,EAClC,EACE,IAAI,EACJ,MAAM,MACoD,EAAE;QAE9D,OAAO,IAAI,KAAK,SAAS;YACvB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;YACpE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7D,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"key.js","sourceRoot":"","sources":["../../src/mutex/key.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,MAAM,OAAO,GAAG;IACL,IAAI,CAAS;IACb,MAAM,CAAQ;IACd,KAAK,CAAiB;IAE/B,YAAY,KAAY,EAAE,IAAY,EAAE,IAAoB;QAC1D,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED,uHAAuH;IACvH,MAAM;QACJ,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;IAYD,GAAG,CACD,IAAkC,EAClC,EACE,IAAI,EACJ,MAAM,MACoD,EAAE;QAE9D,OAAO,IAAI,KAAK,SAAS;YACvB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;YACpE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7D,CAAC;CACF"}
|
|
@@ -9,5 +9,12 @@ export interface LockStore {
|
|
|
9
9
|
acquire(key: string, options?: AcquireOptions): Promise<LockHandle>;
|
|
10
10
|
/** Holds `key` only if that is possible without waiting for another holder. */
|
|
11
11
|
tryAcquire(key: string): Promise<LockHandle | undefined>;
|
|
12
|
+
/**
|
|
13
|
+
* Whether `key` has a holder now. The answer never acquires the key, so it
|
|
14
|
+
* never competes with a caller that acquires it. The holder can change
|
|
15
|
+
* before the answer arrives: show the answer, but never decide from it to
|
|
16
|
+
* acquire the key; an acquire mode decides that.
|
|
17
|
+
*/
|
|
18
|
+
isHeld(key: string): Promise<boolean>;
|
|
12
19
|
}
|
|
13
20
|
//# sourceMappingURL=lock-store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lock-store.d.ts","sourceRoot":"","sources":["../../src/mutex/lock-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,cAAc;IAC7B,gFAAgF;IAChF,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CAClC;AAED,qFAAqF;AACrF,MAAM,WAAW,SAAS;IACxB,+CAA+C;IAC/C,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACpE,+EAA+E;IAC/E,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"lock-store.d.ts","sourceRoot":"","sources":["../../src/mutex/lock-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,cAAc;IAC7B,gFAAgF;IAChF,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CAClC;AAED,qFAAqF;AACrF,MAAM,WAAW,SAAS;IACxB,+CAA+C;IAC/C,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACpE,+EAA+E;IAC/E,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IACzD;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACvC"}
|
package/dist/mutex/mutex.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ export declare class Mutex {
|
|
|
13
13
|
acquire<T, O extends Outcome>(key: string, task: (lease: Lease) => Promise<T>, options: AcquireOptions & {
|
|
14
14
|
mode: AcquireMode<O>;
|
|
15
15
|
}): Promise<OutcomeResults<T>[O]>;
|
|
16
|
+
/** Whether `key` has a holder now, learned without acquiring it. The holder can change before the answer arrives. */
|
|
17
|
+
isHeld(key: string): Promise<boolean>;
|
|
16
18
|
/** A key whose callers wait, unless one call says otherwise. */
|
|
17
19
|
key(name: string, options?: {
|
|
18
20
|
mode?: undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mutex.d.ts","sourceRoot":"","sources":["../../src/mutex/mutex.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAE9E,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,KAAK,EAAE,KAAK,EAAc,MAAM,YAAY,CAAC;AAEpD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAoBjE,qBAAa,KAAK;;gBAGJ,KAAK,EAAE,SAAS;IAI5B,wEAAwE;IACxE,OAAO,CAAC,CAAC,EACP,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,EAClC,OAAO,CAAC,EAAE,cAAc,GAAG;QAAE,IAAI,CAAC,EAAE,SAAS,CAAA;KAAE,GAC9C,OAAO,CAAC,CAAC,CAAC;IACb,oGAAoG;IACpG,OAAO,CAAC,CAAC,EAAE,CAAC,SAAS,OAAO,EAC1B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,EAClC,OAAO,EAAE,cAAc,GAAG;QAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAA;KAAE,GACjD,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAchC,gEAAgE;IAChE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,SAAS,CAAA;KAAE,GAAG,GAAG,CAAC,QAAQ,CAAC;IAChE,sEAAsE;IACtE,GAAG,CAAC,CAAC,SAAS,OAAO,EACnB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAA;KAAE,GAChC,GAAG,CAAC,CAAC,CAAC;CAoDV"}
|
|
1
|
+
{"version":3,"file":"mutex.d.ts","sourceRoot":"","sources":["../../src/mutex/mutex.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAE9E,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,KAAK,EAAE,KAAK,EAAc,MAAM,YAAY,CAAC;AAEpD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAoBjE,qBAAa,KAAK;;gBAGJ,KAAK,EAAE,SAAS;IAI5B,wEAAwE;IACxE,OAAO,CAAC,CAAC,EACP,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,EAClC,OAAO,CAAC,EAAE,cAAc,GAAG;QAAE,IAAI,CAAC,EAAE,SAAS,CAAA;KAAE,GAC9C,OAAO,CAAC,CAAC,CAAC;IACb,oGAAoG;IACpG,OAAO,CAAC,CAAC,EAAE,CAAC,SAAS,OAAO,EAC1B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,EAClC,OAAO,EAAE,cAAc,GAAG;QAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAA;KAAE,GACjD,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAchC,qHAAqH;IACrH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIrC,gEAAgE;IAChE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,SAAS,CAAA;KAAE,GAAG,GAAG,CAAC,QAAQ,CAAC;IAChE,sEAAsE;IACtE,GAAG,CAAC,CAAC,SAAS,OAAO,EACnB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAA;KAAE,GAChC,GAAG,CAAC,CAAC,CAAC;CAoDV"}
|