@zukhruf/mutex 0.3.15 → 0.3.17
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 +7 -8
- package/dist/index.d.ts +3 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -7
- package/dist/index.js.map +1 -1
- package/dist/lock-stores/file-system/file-lock-store.d.ts +4 -9
- package/dist/lock-stores/file-system/file-lock-store.d.ts.map +1 -1
- package/dist/lock-stores/file-system/file-lock-store.js +21 -38
- package/dist/lock-stores/file-system/file-lock-store.js.map +1 -1
- package/dist/lock-stores/file-system/lock-file-store.d.ts +1 -1
- package/dist/lock-stores/file-system/lock-file-store.d.ts.map +1 -1
- package/dist/lock-stores/file-system/lock-file-store.js +15 -24
- package/dist/lock-stores/file-system/lock-file-store.js.map +1 -1
- package/dist/lock-stores/file-system/presence.d.ts +10 -17
- package/dist/lock-stores/file-system/presence.d.ts.map +1 -1
- package/dist/lock-stores/file-system/presence.js +30 -69
- package/dist/lock-stores/file-system/presence.js.map +1 -1
- package/dist/lock-stores/file-system/record-file.d.ts +10 -0
- package/dist/lock-stores/file-system/record-file.d.ts.map +1 -0
- package/dist/lock-stores/file-system/record-file.js +21 -0
- package/dist/lock-stores/file-system/record-file.js.map +1 -0
- package/dist/lock-stores/file-system/ticket-queue-file-store.d.ts +1 -1
- 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 +25 -32
- package/dist/lock-stores/file-system/ticket-queue-file-store.js.map +1 -1
- package/dist/lock-stores/ipc/child-process-connection.d.ts +3 -4
- package/dist/lock-stores/ipc/child-process-connection.d.ts.map +1 -1
- package/dist/lock-stores/ipc/child-process-connection.js +11 -27
- package/dist/lock-stores/ipc/child-process-connection.js.map +1 -1
- package/dist/lock-stores/ipc/ipc-lock-coordinator.d.ts +3 -7
- package/dist/lock-stores/ipc/ipc-lock-coordinator.d.ts.map +1 -1
- package/dist/lock-stores/ipc/ipc-lock-coordinator.js +6 -12
- package/dist/lock-stores/ipc/ipc-lock-coordinator.js.map +1 -1
- package/dist/lock-stores/ipc/ipc-store.d.ts +2 -7
- package/dist/lock-stores/ipc/ipc-store.d.ts.map +1 -1
- package/dist/lock-stores/ipc/ipc-store.js +9 -15
- package/dist/lock-stores/ipc/ipc-store.js.map +1 -1
- package/dist/lock-stores/ipc/process-channel-connection.d.ts +4 -4
- package/dist/lock-stores/ipc/process-channel-connection.d.ts.map +1 -1
- package/dist/lock-stores/ipc/process-channel-connection.js +13 -25
- package/dist/lock-stores/ipc/process-channel-connection.js.map +1 -1
- package/dist/lock-stores/memory/memory-store.d.ts +1 -1
- package/dist/lock-stores/memory/memory-store.d.ts.map +1 -1
- package/dist/lock-stores/memory/memory-store.js +1 -1
- package/dist/lock-stores/memory/memory-store.js.map +1 -1
- package/dist/lock-stores/remote/connection-supervisor.d.ts +4 -4
- package/dist/lock-stores/remote/connection-supervisor.d.ts.map +1 -1
- package/dist/lock-stores/remote/connection-supervisor.js.map +1 -1
- package/dist/lock-stores/remote/connection.d.ts +4 -3
- package/dist/lock-stores/remote/connection.d.ts.map +1 -1
- package/dist/lock-stores/remote/connector.d.ts +5 -5
- package/dist/lock-stores/remote/connector.d.ts.map +1 -1
- package/dist/lock-stores/remote/delegating-lock-store.d.ts +14 -0
- package/dist/lock-stores/remote/delegating-lock-store.d.ts.map +1 -0
- package/dist/lock-stores/remote/delegating-lock-store.js +20 -0
- package/dist/lock-stores/remote/delegating-lock-store.js.map +1 -0
- package/dist/lock-stores/remote/lock-coordinator.d.ts +3 -4
- package/dist/lock-stores/remote/lock-coordinator.d.ts.map +1 -1
- package/dist/lock-stores/remote/lock-coordinator.js +23 -12
- package/dist/lock-stores/remote/lock-coordinator.js.map +1 -1
- package/dist/lock-stores/remote/protocol.d.ts +6 -2
- package/dist/lock-stores/remote/protocol.d.ts.map +1 -1
- package/dist/lock-stores/remote/protocol.js +14 -8
- package/dist/lock-stores/remote/protocol.js.map +1 -1
- package/dist/lock-stores/remote/queries.d.ts +2 -2
- package/dist/lock-stores/remote/queries.d.ts.map +1 -1
- package/dist/lock-stores/remote/queries.js.map +1 -1
- package/dist/lock-stores/remote/remote-lock-client.d.ts +2 -2
- package/dist/lock-stores/remote/remote-lock-client.d.ts.map +1 -1
- package/dist/lock-stores/remote/remote-lock-client.js +15 -8
- package/dist/lock-stores/remote/remote-lock-client.js.map +1 -1
- package/dist/lock-stores/remote/shared-channel-connection.d.ts +27 -0
- package/dist/lock-stores/remote/shared-channel-connection.d.ts.map +1 -0
- package/dist/lock-stores/remote/shared-channel-connection.js +41 -0
- package/dist/lock-stores/remote/shared-channel-connection.js.map +1 -0
- package/dist/lock-stores/socket/advertised-ops-connection.d.ts +3 -3
- package/dist/lock-stores/socket/advertised-ops-connection.d.ts.map +1 -1
- package/dist/lock-stores/socket/advertised-ops-connection.js +4 -1
- package/dist/lock-stores/socket/advertised-ops-connection.js.map +1 -1
- package/dist/lock-stores/socket/electing-connector.d.ts +4 -5
- package/dist/lock-stores/socket/electing-connector.d.ts.map +1 -1
- package/dist/lock-stores/socket/electing-connector.js +43 -50
- package/dist/lock-stores/socket/electing-connector.js.map +1 -1
- package/dist/lock-stores/socket/handshake.d.ts.map +1 -1
- package/dist/lock-stores/socket/handshake.js +6 -5
- package/dist/lock-stores/socket/handshake.js.map +1 -1
- package/dist/lock-stores/socket/json-line.d.ts +6 -0
- package/dist/lock-stores/socket/json-line.d.ts.map +1 -0
- package/dist/lock-stores/socket/json-line.js +8 -0
- package/dist/lock-stores/socket/json-line.js.map +1 -0
- package/dist/lock-stores/socket/leave-errors-to-close.d.ts +9 -0
- package/dist/lock-stores/socket/leave-errors-to-close.d.ts.map +1 -0
- package/dist/lock-stores/socket/leave-errors-to-close.js +10 -0
- package/dist/lock-stores/socket/leave-errors-to-close.js.map +1 -0
- package/dist/lock-stores/socket/local-directory-connector.d.ts.map +1 -1
- package/dist/lock-stores/socket/local-directory-connector.js +1 -1
- package/dist/lock-stores/socket/local-directory-connector.js.map +1 -1
- package/dist/lock-stores/socket/lock-server.d.ts +7 -4
- package/dist/lock-stores/socket/lock-server.d.ts.map +1 -1
- package/dist/lock-stores/socket/lock-server.js +29 -26
- package/dist/lock-stores/socket/lock-server.js.map +1 -1
- package/dist/lock-stores/socket/socket-connection.d.ts +5 -5
- package/dist/lock-stores/socket/socket-connection.d.ts.map +1 -1
- package/dist/lock-stores/socket/socket-connection.js +18 -23
- package/dist/lock-stores/socket/socket-connection.js.map +1 -1
- package/dist/lock-stores/socket/socket-election.d.ts +9 -0
- package/dist/lock-stores/socket/socket-election.d.ts.map +1 -0
- package/dist/lock-stores/socket/socket-election.js +16 -0
- package/dist/lock-stores/socket/socket-election.js.map +1 -0
- package/dist/lock-stores/socket/socket-store.d.ts +1 -1
- package/dist/lock-stores/socket/socket-store.d.ts.map +1 -1
- package/dist/lock-stores/socket/socket-store.js +6 -6
- package/dist/lock-stores/socket/socket-store.js.map +1 -1
- package/dist/lock-stores/sqlite/holder-record.d.ts.map +1 -1
- package/dist/lock-stores/sqlite/holder-record.js +9 -23
- package/dist/lock-stores/sqlite/holder-record.js.map +1 -1
- package/dist/lock-stores/sqlite/sqlite-store.d.ts +6 -7
- package/dist/lock-stores/sqlite/sqlite-store.d.ts.map +1 -1
- package/dist/lock-stores/sqlite/sqlite-store.js +31 -101
- package/dist/lock-stores/sqlite/sqlite-store.js.map +1 -1
- package/dist/lock-stores/thread/parent-port-connection.d.ts +3 -4
- package/dist/lock-stores/thread/parent-port-connection.d.ts.map +1 -1
- package/dist/lock-stores/thread/parent-port-connection.js +7 -13
- package/dist/lock-stores/thread/parent-port-connection.js.map +1 -1
- package/dist/lock-stores/thread/thread-lock-coordinator.d.ts +3 -7
- package/dist/lock-stores/thread/thread-lock-coordinator.d.ts.map +1 -1
- package/dist/lock-stores/thread/thread-lock-coordinator.js +6 -12
- package/dist/lock-stores/thread/thread-lock-coordinator.js.map +1 -1
- package/dist/lock-stores/thread/thread-store.d.ts +2 -7
- package/dist/lock-stores/thread/thread-store.d.ts.map +1 -1
- package/dist/lock-stores/thread/thread-store.js +3 -12
- package/dist/lock-stores/thread/thread-store.js.map +1 -1
- package/dist/lock-stores/thread/worker-connection.d.ts +3 -4
- package/dist/lock-stores/thread/worker-connection.d.ts.map +1 -1
- package/dist/lock-stores/thread/worker-connection.js +6 -18
- package/dist/lock-stores/thread/worker-connection.js.map +1 -1
- package/dist/mutex/key.d.ts +3 -3
- package/dist/mutex/key.d.ts.map +1 -1
- package/dist/mutex/key.js.map +1 -1
- package/dist/mutex/lease.d.ts +2 -9
- package/dist/mutex/lease.d.ts.map +1 -1
- package/dist/mutex/lease.js +17 -12
- package/dist/mutex/lease.js.map +1 -1
- package/dist/mutex/mutex.d.ts +3 -3
- package/dist/mutex/mutex.d.ts.map +1 -1
- package/dist/mutex/mutex.js +2 -2
- package/dist/mutex/mutex.js.map +1 -1
- package/package.json +6 -9
- package/dist/fencing/counter-token-source.d.ts +0 -11
- package/dist/fencing/counter-token-source.d.ts.map +0 -1
- package/dist/fencing/counter-token-source.js +0 -13
- package/dist/fencing/counter-token-source.js.map +0 -1
- package/dist/fencing/epoch-token-source.d.ts +0 -13
- package/dist/fencing/epoch-token-source.d.ts.map +0 -1
- package/dist/fencing/epoch-token-source.js +0 -27
- package/dist/fencing/epoch-token-source.js.map +0 -1
- package/dist/fencing/fencing-token.d.ts +0 -12
- package/dist/fencing/fencing-token.d.ts.map +0 -1
- package/dist/fencing/fencing-token.js +0 -18
- package/dist/fencing/fencing-token.js.map +0 -1
- package/dist/fencing/file-token-source.d.ts +0 -13
- package/dist/fencing/file-token-source.d.ts.map +0 -1
- package/dist/fencing/file-token-source.js +0 -36
- package/dist/fencing/file-token-source.js.map +0 -1
- package/dist/fencing/monotonic-clock-token-source.d.ts +0 -12
- package/dist/fencing/monotonic-clock-token-source.d.ts.map +0 -1
- package/dist/fencing/monotonic-clock-token-source.js +0 -15
- package/dist/fencing/monotonic-clock-token-source.js.map +0 -1
- package/dist/fencing/token-source.d.ts +0 -9
- package/dist/fencing/token-source.d.ts.map +0 -1
- package/dist/fencing/token-source.js +0 -2
- package/dist/fencing/token-source.js.map +0 -1
- package/dist/leader-election/index.d.ts +0 -4
- package/dist/leader-election/index.d.ts.map +0 -1
- package/dist/leader-election/index.js +0 -4
- package/dist/leader-election/index.js.map +0 -1
- package/dist/leader-election/leader-election.d.ts +0 -23
- package/dist/leader-election/leader-election.d.ts.map +0 -1
- package/dist/leader-election/leader-election.js +0 -79
- package/dist/leader-election/leader-election.js.map +0 -1
- package/dist/leader-election/leadership.d.ts +0 -14
- package/dist/leader-election/leadership.d.ts.map +0 -1
- package/dist/leader-election/leadership.js +0 -23
- package/dist/leader-election/leadership.js.map +0 -1
- package/dist/local-directory/local-directory.d.ts +0 -7
- package/dist/local-directory/local-directory.d.ts.map +0 -1
- package/dist/local-directory/local-directory.js +0 -75
- package/dist/local-directory/local-directory.js.map +0 -1
- package/dist/local-directory/network-directory-error.d.ts +0 -8
- package/dist/local-directory/network-directory-error.d.ts.map +0 -1
- package/dist/local-directory/network-directory-error.js +0 -13
- package/dist/local-directory/network-directory-error.js.map +0 -1
- package/dist/mutex/lock-lost-error.d.ts +0 -6
- package/dist/mutex/lock-lost-error.d.ts.map +0 -1
- package/dist/mutex/lock-lost-error.js +0 -10
- package/dist/mutex/lock-lost-error.js.map +0 -1
- package/dist/shared/fs/atomic-write.d.ts +0 -3
- package/dist/shared/fs/atomic-write.d.ts.map +0 -1
- package/dist/shared/fs/atomic-write.js +0 -10
- package/dist/shared/fs/atomic-write.js.map +0 -1
- package/dist/shared/fs/create-exclusive.d.ts +0 -6
- package/dist/shared/fs/create-exclusive.d.ts.map +0 -1
- package/dist/shared/fs/create-exclusive.js +0 -29
- package/dist/shared/fs/create-exclusive.js.map +0 -1
- package/dist/shared/fs/durable-write.d.ts +0 -9
- package/dist/shared/fs/durable-write.d.ts.map +0 -1
- package/dist/shared/fs/durable-write.js +0 -49
- package/dist/shared/fs/durable-write.js.map +0 -1
- package/dist/shared/fs/errno.d.ts +0 -2
- package/dist/shared/fs/errno.d.ts.map +0 -1
- package/dist/shared/fs/errno.js +0 -4
- package/dist/shared/fs/errno.js.map +0 -1
- package/dist/shared/fs/patiently.d.ts +0 -3
- package/dist/shared/fs/patiently.d.ts.map +0 -1
- package/dist/shared/fs/patiently.js +0 -30
- package/dist/shared/fs/patiently.js.map +0 -1
- package/dist/shared/fs/replace-file.d.ts +0 -8
- package/dist/shared/fs/replace-file.d.ts.map +0 -1
- package/dist/shared/fs/replace-file.js +0 -12
- package/dist/shared/fs/replace-file.js.map +0 -1
- package/dist/shared/fs/safe-file-name.d.ts +0 -16
- package/dist/shared/fs/safe-file-name.d.ts.map +0 -1
- package/dist/shared/fs/safe-file-name.js +0 -37
- package/dist/shared/fs/safe-file-name.js.map +0 -1
- package/dist/shared/sqlite/is-busy.d.ts +0 -3
- package/dist/shared/sqlite/is-busy.d.ts.map +0 -1
- package/dist/shared/sqlite/is-busy.js +0 -10
- package/dist/shared/sqlite/is-busy.js.map +0 -1
- package/dist/shared/sqlite/is-cant-open.d.ts +0 -3
- package/dist/shared/sqlite/is-cant-open.d.ts.map +0 -1
- package/dist/shared/sqlite/is-cant-open.js +0 -9
- package/dist/shared/sqlite/is-cant-open.js.map +0 -1
- package/dist/shared/sqlite/is-not-a-database.d.ts +0 -3
- package/dist/shared/sqlite/is-not-a-database.d.ts.map +0 -1
- package/dist/shared/sqlite/is-not-a-database.js +0 -9
- package/dist/shared/sqlite/is-not-a-database.js.map +0 -1
|
@@ -3,13 +3,13 @@ import type { Socket } from 'node:net';
|
|
|
3
3
|
import type { Connection, ConnectionEvents } from '../remote/connection.ts';
|
|
4
4
|
/**
|
|
5
5
|
* Newline-delimited JSON over a stream socket. A stream has no message
|
|
6
|
-
* boundaries (writes arrive merged and split),
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* boundaries (writes arrive merged and split), so each message is one line
|
|
7
|
+
* (see `jsonLine`). A line that is not JSON breaks the framing, so it closes
|
|
8
|
+
* the connection; any JSON value goes to the listener, which checks it.
|
|
9
9
|
*/
|
|
10
|
-
export declare class SocketConnection<Outgoing
|
|
10
|
+
export declare class SocketConnection<Outgoing> extends EventEmitter<ConnectionEvents> implements Connection<Outgoing> {
|
|
11
11
|
#private;
|
|
12
|
-
constructor(socket: Socket
|
|
12
|
+
constructor(socket: Socket);
|
|
13
13
|
send(message: Outgoing): Promise<void>;
|
|
14
14
|
ref(): void;
|
|
15
15
|
unref(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socket-connection.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/socket/socket-connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"socket-connection.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/socket/socket-connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAIvC,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAI5E;;;;;GAKG;AACH,qBAAa,gBAAgB,CAAC,QAAQ,CACpC,SAAQ,YAAY,CAAC,gBAAgB,CACrC,YAAW,UAAU,CAAC,QAAQ,CAAC;;gBAMnB,MAAM,EAAE,MAAM;IAkB1B,IAAI,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAItC,GAAG;IAIH,KAAK;IAIL,KAAK;CAGN"}
|
|
@@ -1,43 +1,38 @@
|
|
|
1
1
|
import { EventEmitter } from 'node:events';
|
|
2
2
|
import { createInterface } from 'node:readline';
|
|
3
|
+
import { promisify } from 'node:util';
|
|
4
|
+
import { jsonLine } from "./json-line.js";
|
|
5
|
+
import { leaveErrorsToClose } from "./leave-errors-to-close.js";
|
|
3
6
|
/**
|
|
4
7
|
* Newline-delimited JSON over a stream socket. A stream has no message
|
|
5
|
-
* boundaries (writes arrive merged and split),
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
+
* boundaries (writes arrive merged and split), so each message is one line
|
|
9
|
+
* (see `jsonLine`). A line that is not JSON breaks the framing, so it closes
|
|
10
|
+
* the connection; any JSON value goes to the listener, which checks it.
|
|
8
11
|
*/
|
|
9
12
|
export class SocketConnection extends EventEmitter {
|
|
10
13
|
#socket;
|
|
11
|
-
|
|
14
|
+
/** A write after the socket closed reports the error through its callback. */
|
|
15
|
+
#write;
|
|
16
|
+
constructor(socket) {
|
|
12
17
|
super();
|
|
13
18
|
this.#socket = socket;
|
|
14
|
-
|
|
15
|
-
socket
|
|
16
|
-
createInterface({ input: socket, crlfDelay: Infinity })
|
|
17
|
-
|
|
19
|
+
this.#write = promisify(socket.write).bind(socket);
|
|
20
|
+
leaveErrorsToClose(socket);
|
|
21
|
+
const lines = createInterface({ input: socket, crlfDelay: Infinity });
|
|
22
|
+
lines.on('line', (line) => {
|
|
18
23
|
try {
|
|
19
|
-
|
|
20
|
-
if (isIncoming(parsed))
|
|
21
|
-
this.emit('message', parsed);
|
|
22
|
-
else
|
|
23
|
-
this.close();
|
|
24
|
+
this.emit('message', JSON.parse(line));
|
|
24
25
|
}
|
|
25
26
|
catch {
|
|
26
27
|
this.close();
|
|
27
28
|
}
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
});
|
|
30
|
+
// readline re-emits the socket's errors (e.g. EPIPE when the peer died).
|
|
31
|
+
leaveErrorsToClose(lines);
|
|
31
32
|
socket.once('close', () => this.emit('close'));
|
|
32
33
|
}
|
|
33
34
|
send(message) {
|
|
34
|
-
return
|
|
35
|
-
if (!this.#socket.writable) {
|
|
36
|
-
reject(new Error('The socket is closed.'));
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
this.#socket.write(`${JSON.stringify(message)}\n`, (error) => error ? reject(error) : resolve());
|
|
40
|
-
});
|
|
35
|
+
return this.#write(jsonLine(message));
|
|
41
36
|
}
|
|
42
37
|
ref() {
|
|
43
38
|
this.#socket.ref();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socket-connection.js","sourceRoot":"","sources":["../../../src/lock-stores/socket/socket-connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"socket-connection.js","sourceRoot":"","sources":["../../../src/lock-stores/socket/socket-connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE;;;;;GAKG;AACH,MAAM,OAAO,gBACX,SAAQ,YAA8B;IAG7B,OAAO,CAAS;IACzB,8EAA8E;IACrE,MAAM,CAAkC;IAEjD,YAAY,MAAc;QACxB,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,MAAM,GAAG,SAAS,CAAe,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjE,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAC3B,MAAM,KAAK,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;QACtE,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACxB,IAAI,CAAC;gBACH,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YACzC,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,CAAC;QACH,CAAC,CAAC,CAAC;QACH,yEAAyE;QACzE,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACjD,CAAC;IAED,IAAI,CAAC,OAAiB;QACpB,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IACxC,CAAC;IAED,GAAG;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;IACrB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC;CACF"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SqliteElection } from '@zukhruf/election';
|
|
2
|
+
/**
|
|
3
|
+
* The election of the socket stores that share `directory`. Every published
|
|
4
|
+
* version claims `leader.lock` and counts terms in `leader.epoch`
|
|
5
|
+
* (wire-compatibility.test.ts pins both), so stores of two versions elect one
|
|
6
|
+
* leader between them.
|
|
7
|
+
*/
|
|
8
|
+
export declare function socketElection(directory: string, pollInterval: number): SqliteElection;
|
|
9
|
+
//# sourceMappingURL=socket-election.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"socket-election.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/socket/socket-election.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,cAAc,CAOhB"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SqliteElection } from '@zukhruf/election';
|
|
2
|
+
/**
|
|
3
|
+
* The election of the socket stores that share `directory`. Every published
|
|
4
|
+
* version claims `leader.lock` and counts terms in `leader.epoch`
|
|
5
|
+
* (wire-compatibility.test.ts pins both), so stores of two versions elect one
|
|
6
|
+
* leader between them.
|
|
7
|
+
*/
|
|
8
|
+
export function socketElection(directory, pollInterval) {
|
|
9
|
+
return new SqliteElection({
|
|
10
|
+
directory,
|
|
11
|
+
claimFile: 'leader.lock',
|
|
12
|
+
epochFile: 'leader.epoch',
|
|
13
|
+
pollInterval,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=socket-election.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"socket-election.js","sourceRoot":"","sources":["../../../src/lock-stores/socket/socket-election.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAC5B,SAAiB,EACjB,YAAoB;IAEpB,OAAO,IAAI,cAAc,CAAC;QACxB,SAAS;QACT,SAAS,EAAE,aAAa;QACxB,SAAS,EAAE,cAAc;QACzB,YAAY;KACb,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -19,7 +19,7 @@ export interface SocketStoreOptions {
|
|
|
19
19
|
* a survivor takes over, and holders reassert their keys during the new
|
|
20
20
|
* leader's grace window. Tokens carry the term's epoch, so a holder that
|
|
21
21
|
* missed the window (for example while frozen) is fenced off by any resource
|
|
22
|
-
* that checks tokens, and its lease's signal aborts with `
|
|
22
|
+
* that checks tokens, and its lease's signal aborts with `LeaseLostError`.
|
|
23
23
|
*/
|
|
24
24
|
export declare class SocketStore extends EventEmitter<{
|
|
25
25
|
role: [SocketRole];
|
|
@@ -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;
|
|
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;AAG3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAW3E,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"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import { EventEmitter } from 'node:events';
|
|
3
3
|
import { join, resolve } from 'node:path';
|
|
4
|
-
import { LeaderElection } from "../../leader-election/leader-election.js";
|
|
5
4
|
import { ConnectionSupervisor } from "../remote/connection-supervisor.js";
|
|
6
5
|
import { RemoteLockClient } from "../remote/remote-lock-client.js";
|
|
7
6
|
import { ElectingConnector } from "./electing-connector.js";
|
|
8
7
|
import { LocalDirectoryConnector } from "./local-directory-connector.js";
|
|
9
8
|
import { LockServer } from "./lock-server.js";
|
|
9
|
+
import { socketElection } from "./socket-election.js";
|
|
10
10
|
/** macOS allows 104 bytes including the terminating NUL; Linux allows 108. */
|
|
11
11
|
const SOCKET_PATH_LIMIT = 103;
|
|
12
12
|
/**
|
|
@@ -17,7 +17,7 @@ const SOCKET_PATH_LIMIT = 103;
|
|
|
17
17
|
* a survivor takes over, and holders reassert their keys during the new
|
|
18
18
|
* leader's grace window. Tokens carry the term's epoch, so a holder that
|
|
19
19
|
* missed the window (for example while frozen) is fenced off by any resource
|
|
20
|
-
* that checks tokens, and its lease's signal aborts with `
|
|
20
|
+
* that checks tokens, and its lease's signal aborts with `LeaseLostError`.
|
|
21
21
|
*/
|
|
22
22
|
export class SocketStore extends EventEmitter {
|
|
23
23
|
#client;
|
|
@@ -28,14 +28,14 @@ export class SocketStore extends EventEmitter {
|
|
|
28
28
|
const socketPath = socketPathFor(directory);
|
|
29
29
|
this.#client = new RemoteLockClient(new ConnectionSupervisor(new LocalDirectoryConnector(directory, new ElectingConnector({
|
|
30
30
|
socketPath,
|
|
31
|
-
election:
|
|
31
|
+
election: socketElection(directory, pollInterval),
|
|
32
32
|
pollInterval,
|
|
33
|
-
serve: async (
|
|
33
|
+
serve: async (term) => {
|
|
34
34
|
// Until serving has fully started, a failure closes the new server, so no server outlives its term.
|
|
35
35
|
await using starting = new AsyncDisposableStack();
|
|
36
|
-
starting.adopt(await LockServer.start(socketPath,
|
|
36
|
+
starting.adopt(await LockServer.start(socketPath, term, {
|
|
37
37
|
// The first term of a directory has no predecessor to wait for.
|
|
38
|
-
graceWindow:
|
|
38
|
+
graceWindow: term.epoch > 1n ? graceWindow : 0,
|
|
39
39
|
}), (started) => started.close());
|
|
40
40
|
this.emit('role', 'leader');
|
|
41
41
|
this.#servers.use(starting.move());
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"socket-store.js","sourceRoot":"","sources":["../../../src/lock-stores/socket/socket-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"holder-record.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/sqlite/holder-record.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"holder-record.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/sqlite/holder-record.ts"],"names":[],"mappings":"AASA;;;;;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;CAkC9B"}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import { readFileSync } from 'node:fs';
|
|
2
1
|
import { mkdir, readdir, unlink } from 'node:fs/promises';
|
|
3
2
|
import { basename, join } from 'node:path';
|
|
4
|
-
import { atomicWrite } from
|
|
5
|
-
import { isErrno } from "../../shared/fs/errno.js";
|
|
6
|
-
import { patiently } from "../../shared/fs/patiently.js";
|
|
3
|
+
import { atomicWrite, patiently } from '@zukhruf/fs';
|
|
7
4
|
import { Caller } from "../file-system/caller.js";
|
|
8
5
|
import { Presence } from "../file-system/presence.js";
|
|
6
|
+
import { readRecord } from "../file-system/record-file.js";
|
|
9
7
|
/**
|
|
10
8
|
* Names the holder of a SQLite lock in `<lock>.holder/caller`, beside the
|
|
11
9
|
* holder's presence. A look reads these two files and never the lock that
|
|
@@ -26,14 +24,10 @@ export class HolderRecord {
|
|
|
26
24
|
async announce() {
|
|
27
25
|
const me = Caller.current();
|
|
28
26
|
await mkdir(this.#folder, { recursive: true });
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
catch (error) {
|
|
34
|
-
await presence.withdraw();
|
|
35
|
-
throw error;
|
|
36
|
-
}
|
|
27
|
+
await using announcing = new AsyncDisposableStack();
|
|
28
|
+
const presence = announcing.adopt(Presence.claim(this.#path, me), (claimed) => claimed.withdraw());
|
|
29
|
+
await atomicWrite(this.#path, me.serialize());
|
|
30
|
+
announcing.move();
|
|
37
31
|
await this.#clearEarlierHolders(me);
|
|
38
32
|
return {
|
|
39
33
|
[Symbol.asyncDispose]: () => presence.releaseAfter(() => patiently(() => unlink(this.#path))),
|
|
@@ -59,17 +53,9 @@ export class HolderRecord {
|
|
|
59
53
|
.map((name) => unlink(join(this.#folder, name)).catch(() => { })));
|
|
60
54
|
}
|
|
61
55
|
async #read() {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
}
|
|
56
|
+
const content = await readRecord(this.#path);
|
|
57
|
+
if (content === undefined)
|
|
58
|
+
return undefined;
|
|
73
59
|
try {
|
|
74
60
|
return Caller.parse(content);
|
|
75
61
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"holder-record.js","sourceRoot":"","sources":["../../../src/lock-stores/sqlite/holder-record.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"holder-record.js","sourceRoot":"","sources":["../../../src/lock-stores/sqlite/holder-record.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,10 +2,8 @@ import type { LockHandle } from '../../mutex/lease.ts';
|
|
|
2
2
|
import type { AcquireOptions } from '../../mutex/lock-store.ts';
|
|
3
3
|
import { FileLockStore } from '../file-system/file-lock-store.ts';
|
|
4
4
|
/**
|
|
5
|
-
* Holds
|
|
6
|
-
*
|
|
7
|
-
* crash never leaves a key locked. Keep the default rollback journal: in WAL
|
|
8
|
-
* mode an exclusive transaction no longer blocks readers.
|
|
5
|
+
* Holds the file lock of the key's database file. The kernel releases it when
|
|
6
|
+
* the holder dies, so a crash never leaves a key locked.
|
|
9
7
|
*
|
|
10
8
|
* Even a read of that file makes it busy for a caller that tries to take it,
|
|
11
9
|
* so the holder also names itself in a holder record, which a look reads
|
|
@@ -18,9 +16,10 @@ import { FileLockStore } from '../file-system/file-lock-store.ts';
|
|
|
18
16
|
export declare class SqliteStore extends FileLockStore {
|
|
19
17
|
#private;
|
|
20
18
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* that versions
|
|
19
|
+
* Published versions keep the rollback journal of a key's database at
|
|
20
|
+
* `<path>-journal`. New versions keep it in memory, but a key keeps the file
|
|
21
|
+
* name that those versions gave it, so both versions share its lock. The
|
|
22
|
+
* holder folder `<path>.holder` is shorter.
|
|
24
23
|
*/
|
|
25
24
|
protected readonly longestSuffix: number;
|
|
26
25
|
acquire(key: string, options?: AcquireOptions): Promise<LockHandle>;
|
|
@@ -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;
|
|
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;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAIlE;;;;;;;;;;;GAWG;AACH,qBAAa,WAAY,SAAQ,aAAa;;IAC5C;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,CAAC,aAAa,SAAqB;IAGtC,OAAO,CACpB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,UAAU,CAAC;IAOP,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;cASvD,IAAI,CAClB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,WAAW,GAAG,SAAS,GAC9B,OAAO,CAAC,eAAe,CAAC;cASX,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAQ3E,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAGnD"}
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { isBusy } from "../../shared/sqlite/is-busy.js";
|
|
1
|
+
import { FileLock } from '@zukhruf/fs';
|
|
3
2
|
import { FileLockStore } from "../file-system/file-lock-store.js";
|
|
4
3
|
import { MemoryStore } from "../memory/memory-store.js";
|
|
5
4
|
import { HolderRecord } from "./holder-record.js";
|
|
6
5
|
/**
|
|
7
|
-
* Holds
|
|
8
|
-
*
|
|
9
|
-
* crash never leaves a key locked. Keep the default rollback journal: in WAL
|
|
10
|
-
* mode an exclusive transaction no longer blocks readers.
|
|
6
|
+
* Holds the file lock of the key's database file. The kernel releases it when
|
|
7
|
+
* the holder dies, so a crash never leaves a key locked.
|
|
11
8
|
*
|
|
12
9
|
* Even a read of that file makes it busy for a caller that tries to take it,
|
|
13
10
|
* so the holder also names itself in a holder record, which a look reads
|
|
@@ -19,123 +16,56 @@ import { HolderRecord } from "./holder-record.js";
|
|
|
19
16
|
*/
|
|
20
17
|
export class SqliteStore extends FileLockStore {
|
|
21
18
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* that versions
|
|
19
|
+
* Published versions keep the rollback journal of a key's database at
|
|
20
|
+
* `<path>-journal`. New versions keep it in memory, but a key keeps the file
|
|
21
|
+
* name that those versions gave it, so both versions share its lock. The
|
|
22
|
+
* holder folder `<path>.holder` is shorter.
|
|
25
23
|
*/
|
|
26
24
|
longestSuffix = '-journal'.length;
|
|
27
25
|
#inProcess = new MemoryStore();
|
|
28
26
|
async acquire(key, options = {}) {
|
|
27
|
+
await using turn = new AsyncDisposableStack();
|
|
29
28
|
// Joining the in-process queue is synchronous, so the order is the order of the calls.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return withTurn(await super.acquire(key, options), turn);
|
|
33
|
-
}
|
|
34
|
-
catch (error) {
|
|
35
|
-
await turn[Symbol.asyncDispose]();
|
|
36
|
-
throw error;
|
|
37
|
-
}
|
|
29
|
+
turn.use(await this.#inProcess.acquire(key, options));
|
|
30
|
+
return withTurn(await super.acquire(key, options), turn);
|
|
38
31
|
}
|
|
39
32
|
async tryAcquire(key) {
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
await using turn = new AsyncDisposableStack();
|
|
34
|
+
const inProcess = await this.#inProcess.tryAcquire(key);
|
|
35
|
+
if (!inProcess)
|
|
42
36
|
return undefined;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return withTurn(lease, turn);
|
|
47
|
-
}
|
|
48
|
-
catch (error) {
|
|
49
|
-
await turn[Symbol.asyncDispose]();
|
|
50
|
-
throw error;
|
|
51
|
-
}
|
|
52
|
-
await turn[Symbol.asyncDispose]();
|
|
53
|
-
return undefined;
|
|
37
|
+
turn.use(inProcess);
|
|
38
|
+
const lease = await super.tryAcquire(key);
|
|
39
|
+
return lease && withTurn(lease, turn);
|
|
54
40
|
}
|
|
55
41
|
async lock(path, signal) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
catch (error) {
|
|
63
|
-
database.close();
|
|
64
|
-
throw error;
|
|
65
|
-
}
|
|
66
|
-
return holding(path, database);
|
|
42
|
+
await using held = new AsyncDisposableStack();
|
|
43
|
+
const lock = held.use(FileLock.open(path));
|
|
44
|
+
await this.poll(async () => (lock.tryLock() ? true : undefined), signal);
|
|
45
|
+
// The release removes the record, then lets the lock go even when the record stays.
|
|
46
|
+
held.use(await new HolderRecord(path).announce());
|
|
47
|
+
return held.move();
|
|
67
48
|
}
|
|
68
49
|
async tryLock(path) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
database.close();
|
|
76
|
-
throw error;
|
|
77
|
-
}
|
|
78
|
-
if (begun)
|
|
79
|
-
return holding(path, database);
|
|
80
|
-
database.close();
|
|
81
|
-
return undefined;
|
|
50
|
+
await using held = new AsyncDisposableStack();
|
|
51
|
+
const lock = held.use(FileLock.open(path));
|
|
52
|
+
if (!lock.tryLock())
|
|
53
|
+
return undefined;
|
|
54
|
+
held.use(await new HolderRecord(path).announce());
|
|
55
|
+
return held.move();
|
|
82
56
|
}
|
|
83
57
|
isHeldAt(path) {
|
|
84
58
|
return new HolderRecord(path).isPresent();
|
|
85
59
|
}
|
|
86
60
|
}
|
|
87
|
-
/** Starts the exclusive transaction, or reports that another connection holds it. */
|
|
88
|
-
function begin(database) {
|
|
89
|
-
try {
|
|
90
|
-
database.exec('BEGIN EXCLUSIVE');
|
|
91
|
-
return true;
|
|
92
|
-
}
|
|
93
|
-
catch (error) {
|
|
94
|
-
if (isBusy(error))
|
|
95
|
-
return false;
|
|
96
|
-
throw error;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
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
|
-
});
|
|
107
|
-
return {
|
|
108
|
-
[Symbol.asyncDispose]: async () => {
|
|
109
|
-
try {
|
|
110
|
-
await record[Symbol.asyncDispose]();
|
|
111
|
-
}
|
|
112
|
-
finally {
|
|
113
|
-
unlock(database);
|
|
114
|
-
}
|
|
115
|
-
},
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
function unlock(database) {
|
|
119
|
-
try {
|
|
120
|
-
database.exec('ROLLBACK');
|
|
121
|
-
}
|
|
122
|
-
finally {
|
|
123
|
-
database.close();
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
61
|
/** Releases the database lock first, then lets the next caller in this process try. */
|
|
127
62
|
function withTurn(handle, turn) {
|
|
63
|
+
turn.use(handle);
|
|
64
|
+
const release = turn.move();
|
|
128
65
|
return {
|
|
129
66
|
token: handle.token,
|
|
130
67
|
signal: handle.signal,
|
|
131
|
-
[Symbol.asyncDispose]:
|
|
132
|
-
try {
|
|
133
|
-
await handle[Symbol.asyncDispose]();
|
|
134
|
-
}
|
|
135
|
-
finally {
|
|
136
|
-
await turn[Symbol.asyncDispose]();
|
|
137
|
-
}
|
|
138
|
-
},
|
|
68
|
+
[Symbol.asyncDispose]: () => release.disposeAsync(),
|
|
139
69
|
};
|
|
140
70
|
}
|
|
141
71
|
//# sourceMappingURL=sqlite-store.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-store.js","sourceRoot":"","sources":["../../../src/lock-stores/sqlite/sqlite-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"sqlite-store.js","sourceRoot":"","sources":["../../../src/lock-stores/sqlite/sqlite-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAIvC,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,WAAY,SAAQ,aAAa;IAC5C;;;;;OAKG;IACgB,aAAa,GAAG,UAAU,CAAC,MAAM,CAAC;IAC5C,UAAU,GAAG,IAAI,WAAW,EAAE,CAAC;IAE/B,KAAK,CAAC,OAAO,CACpB,GAAW,EACX,UAA0B,EAAE;QAE5B,YAAY,IAAI,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC9C,uFAAuF;QACvF,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;QACtD,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC;IAC3D,CAAC;IAEQ,KAAK,CAAC,UAAU,CAAC,GAAW;QACnC,YAAY,IAAI,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC9C,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACxD,IAAI,CAAC,SAAS;YAAE,OAAO,SAAS,CAAC;QACjC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACpB,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAC1C,OAAO,KAAK,IAAI,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACxC,CAAC;IAES,KAAK,CAAC,IAAI,CAClB,IAAY,EACZ,MAA+B;QAE/B,YAAY,IAAI,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3C,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;QACzE,oFAAoF;QACpF,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;IACrB,CAAC;IAES,KAAK,CAAC,OAAO,CAAC,IAAY;QAClC,YAAY,IAAI,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3C,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YAAE,OAAO,SAAS,CAAC;QACtC,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;IACrB,CAAC;IAES,QAAQ,CAAC,IAAY;QAC7B,OAAO,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;IAC5C,CAAC;CACF;AAED,uFAAuF;AACvF,SAAS,QAAQ,CAAC,MAAkB,EAAE,IAA0B;IAC9D,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACjB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE;KACpD,CAAC;AACJ,CAAC"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { EventEmitter } from 'node:events';
|
|
2
1
|
import type { MessagePort } from 'node:worker_threads';
|
|
3
|
-
import type {
|
|
4
|
-
import {
|
|
2
|
+
import type { LockRequest } from '../remote/protocol.ts';
|
|
3
|
+
import { SharedChannelConnection } from '../remote/shared-channel-connection.ts';
|
|
5
4
|
/**
|
|
6
5
|
* A worker thread's end of the message port to the thread that started it.
|
|
7
6
|
* A `message` listener keeps the worker alive, so this adapter listens only
|
|
@@ -9,7 +8,7 @@ import { type LockRequest, type LockResponse } from '../remote/protocol.ts';
|
|
|
9
8
|
* coordinator cannot stop without its workers stopping too, so `close` is
|
|
10
9
|
* never reported.
|
|
11
10
|
*/
|
|
12
|
-
export declare class ParentPortConnection extends
|
|
11
|
+
export declare class ParentPortConnection extends SharedChannelConnection<LockRequest> {
|
|
13
12
|
#private;
|
|
14
13
|
constructor(port: MessagePort);
|
|
15
14
|
send(request: LockRequest): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parent-port-connection.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/thread/parent-port-connection.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"parent-port-connection.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/thread/parent-port-connection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AAEjF;;;;;;GAMG;AACH,qBAAa,oBAAqB,SAAQ,uBAAuB,CAAC,WAAW,CAAC;;gBAGhE,IAAI,EAAE,WAAW;IAKvB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,uFAAuF;IACvF,GAAG;IAKH,KAAK;IAIL,KAAK;CAGN"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { isLockResponse, } from "../remote/protocol.js";
|
|
1
|
+
import { wrap } from "../remote/envelope.js";
|
|
2
|
+
import { SharedChannelConnection } from "../remote/shared-channel-connection.js";
|
|
4
3
|
/**
|
|
5
4
|
* A worker thread's end of the message port to the thread that started it.
|
|
6
5
|
* A `message` listener keeps the worker alive, so this adapter listens only
|
|
@@ -8,15 +7,10 @@ import { isLockResponse, } from "../remote/protocol.js";
|
|
|
8
7
|
* coordinator cannot stop without its workers stopping too, so `close` is
|
|
9
8
|
* never reported.
|
|
10
9
|
*/
|
|
11
|
-
export class ParentPortConnection extends
|
|
10
|
+
export class ParentPortConnection extends SharedChannelConnection {
|
|
12
11
|
#port;
|
|
13
|
-
#onMessage = (envelope) => {
|
|
14
|
-
const response = unwrap(envelope);
|
|
15
|
-
if (isLockResponse(response))
|
|
16
|
-
this.emit('message', response);
|
|
17
|
-
};
|
|
18
12
|
constructor(port) {
|
|
19
|
-
super();
|
|
13
|
+
super(port, []);
|
|
20
14
|
this.#port = port;
|
|
21
15
|
}
|
|
22
16
|
async send(request) {
|
|
@@ -24,11 +18,11 @@ export class ParentPortConnection extends EventEmitter {
|
|
|
24
18
|
}
|
|
25
19
|
/** Removes the listener before it adds it, so a second `ref` does not listen twice. */
|
|
26
20
|
ref() {
|
|
27
|
-
this.
|
|
28
|
-
this
|
|
21
|
+
this.stopListening();
|
|
22
|
+
this.listen();
|
|
29
23
|
}
|
|
30
24
|
unref() {
|
|
31
|
-
this
|
|
25
|
+
this.stopListening();
|
|
32
26
|
}
|
|
33
27
|
close() {
|
|
34
28
|
this.unref();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parent-port-connection.js","sourceRoot":"","sources":["../../../src/lock-stores/thread/parent-port-connection.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"parent-port-connection.js","sourceRoot":"","sources":["../../../src/lock-stores/thread/parent-port-connection.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAE7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AAEjF;;;;;;GAMG;AACH,MAAM,OAAO,oBAAqB,SAAQ,uBAAoC;IACnE,KAAK,CAAc;IAE5B,YAAY,IAAiB;QAC3B,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAChB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAoB;QAC7B,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACxC,CAAC;IAED,uFAAuF;IACvF,GAAG;QACD,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;CACF"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Worker } from 'node:worker_threads';
|
|
2
|
-
import type
|
|
3
|
-
import
|
|
4
|
-
import type { AcquireOptions, LockStore } from '../../mutex/lock-store.ts';
|
|
2
|
+
import { type TokenSource } from '@zukhruf/fencing';
|
|
3
|
+
import { DelegatingLockStore } from '../remote/delegating-lock-store.ts';
|
|
5
4
|
export interface ThreadLockCoordinatorOptions {
|
|
6
5
|
/** Defaults to an in-memory counter, which lives as long as this process. */
|
|
7
6
|
tokens?: TokenSource;
|
|
@@ -11,12 +10,9 @@ export interface ThreadLockCoordinatorOptions {
|
|
|
11
10
|
* which use `ThreadStore`. One thread decides every grant, so two threads can
|
|
12
11
|
* never both be granted a key. Its reach is one process.
|
|
13
12
|
*/
|
|
14
|
-
export declare class ThreadLockCoordinator
|
|
13
|
+
export declare class ThreadLockCoordinator extends DelegatingLockStore {
|
|
15
14
|
#private;
|
|
16
15
|
constructor({ tokens, }?: ThreadLockCoordinatorOptions);
|
|
17
|
-
acquire(key: string, options?: AcquireOptions): Promise<LockHandle>;
|
|
18
|
-
tryAcquire(key: string): Promise<LockHandle | undefined>;
|
|
19
|
-
isHeld(key: string): Promise<boolean>;
|
|
20
16
|
/** Serves `worker`. When the thread stops, everything it held or waited for is released. */
|
|
21
17
|
adopt(worker: Worker): void;
|
|
22
18
|
}
|