@zukhruf/single-flight 0.3.16 → 0.3.18
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 +13 -12
- package/dist/client/flight-client.d.ts +4 -4
- package/dist/client/flight-client.d.ts.map +1 -1
- package/dist/client/flight-client.js +20 -10
- package/dist/client/flight-client.js.map +1 -1
- package/dist/connection/connection-supervisor.d.ts +4 -4
- package/dist/connection/connection-supervisor.d.ts.map +1 -1
- package/dist/connection/connection-supervisor.js.map +1 -1
- package/dist/connection/connection.d.ts +4 -3
- package/dist/connection/connection.d.ts.map +1 -1
- package/dist/connection/connector.d.ts +5 -5
- package/dist/connection/connector.d.ts.map +1 -1
- package/dist/connection/electing-connector.d.ts +4 -5
- package/dist/connection/electing-connector.d.ts.map +1 -1
- package/dist/connection/electing-connector.js +38 -42
- package/dist/connection/electing-connector.js.map +1 -1
- package/dist/connection/flight-election.d.ts +11 -0
- package/dist/connection/flight-election.d.ts.map +1 -0
- package/dist/connection/flight-election.js +18 -0
- package/dist/connection/flight-election.js.map +1 -0
- package/dist/connection/handshake.d.ts.map +1 -1
- package/dist/connection/handshake.js +6 -5
- package/dist/connection/handshake.js.map +1 -1
- package/dist/connection/json-line.d.ts +6 -0
- package/dist/connection/json-line.d.ts.map +1 -0
- package/dist/connection/json-line.js +8 -0
- package/dist/connection/json-line.js.map +1 -0
- package/dist/connection/leave-errors-to-close.d.ts +9 -0
- package/dist/connection/leave-errors-to-close.d.ts.map +1 -0
- package/dist/connection/leave-errors-to-close.js +10 -0
- package/dist/connection/leave-errors-to-close.js.map +1 -0
- package/dist/connection/local-directory-connector.d.ts.map +1 -1
- package/dist/connection/local-directory-connector.js +1 -1
- package/dist/connection/local-directory-connector.js.map +1 -1
- package/dist/connection/socket-connection.d.ts +5 -5
- package/dist/connection/socket-connection.d.ts.map +1 -1
- package/dist/connection/socket-connection.js +21 -23
- package/dist/connection/socket-connection.js.map +1 -1
- package/dist/coordinator/flight-coordinator.d.ts +3 -3
- package/dist/coordinator/flight-coordinator.d.ts.map +1 -1
- package/dist/coordinator/flight-coordinator.js +12 -18
- package/dist/coordinator/flight-coordinator.js.map +1 -1
- package/dist/coordinator/flight-server.d.ts +7 -3
- package/dist/coordinator/flight-server.d.ts.map +1 -1
- package/dist/coordinator/flight-server.js +29 -25
- package/dist/coordinator/flight-server.js.map +1 -1
- package/dist/coordinator/flight.d.ts +4 -2
- package/dist/coordinator/flight.d.ts.map +1 -1
- package/dist/coordinator/flight.js +9 -5
- package/dist/coordinator/flight.js.map +1 -1
- package/dist/coordinator/party.d.ts +11 -2
- package/dist/coordinator/party.d.ts.map +1 -1
- package/dist/coordinator/party.js +15 -15
- package/dist/coordinator/party.js.map +1 -1
- package/dist/coordinator/session.d.ts +2 -2
- package/dist/coordinator/session.d.ts.map +1 -1
- package/dist/coordinator/session.js +9 -4
- package/dist/coordinator/session.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/protocol/flight-protocol.d.ts +6 -2
- package/dist/protocol/flight-protocol.d.ts.map +1 -1
- package/dist/protocol/flight-protocol.js +17 -10
- package/dist/protocol/flight-protocol.js.map +1 -1
- package/dist/single-flight.d.ts +7 -5
- package/dist/single-flight.d.ts.map +1 -1
- package/dist/single-flight.js +21 -16
- package/dist/single-flight.js.map +1 -1
- package/package.json +6 -5
- package/dist/election/leader-election.d.ts +0 -24
- package/dist/election/leader-election.d.ts.map +0 -1
- package/dist/election/leader-election.js +0 -80
- package/dist/election/leader-election.js.map +0 -1
- package/dist/election/leadership.d.ts +0 -14
- package/dist/election/leadership.d.ts.map +0 -1
- package/dist/election/leadership.js +0 -23
- package/dist/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/shared/fs/durable-write.d.ts +0 -7
- package/dist/shared/fs/durable-write.d.ts.map +0 -1
- package/dist/shared/fs/durable-write.js +0 -47
- 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/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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handshake.js","sourceRoot":"","sources":["../../src/connection/handshake.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"handshake.js","sourceRoot":"","sources":["../../src/connection/handshake.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-line.d.ts","sourceRoot":"","sources":["../../src/connection/json-line.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAEjD"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One message as one line of the socket's newline-delimited JSON. JSON escapes
|
|
3
|
+
* newlines inside strings, so one line is always one message.
|
|
4
|
+
*/
|
|
5
|
+
export function jsonLine(message) {
|
|
6
|
+
return `${JSON.stringify(message)}\n`;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=json-line.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-line.js","sourceRoot":"","sources":["../../src/connection/json-line.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAgB;IACvC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { EventEmitter } from 'node:events';
|
|
2
|
+
/**
|
|
3
|
+
* Keeps the errors of a socket, or of a stream reading it, from stopping the
|
|
4
|
+
* process: an `error` with no listener does that. Every such error is followed
|
|
5
|
+
* by the socket's `close`, which is where the lost connection is reported, so
|
|
6
|
+
* this listener does nothing.
|
|
7
|
+
*/
|
|
8
|
+
export declare function leaveErrorsToClose(emitter: EventEmitter): void;
|
|
9
|
+
//# sourceMappingURL=leave-errors-to-close.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"leave-errors-to-close.d.ts","sourceRoot":"","sources":["../../src/connection/leave-errors-to-close.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAE9D"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keeps the errors of a socket, or of a stream reading it, from stopping the
|
|
3
|
+
* process: an `error` with no listener does that. Every such error is followed
|
|
4
|
+
* by the socket's `close`, which is where the lost connection is reported, so
|
|
5
|
+
* this listener does nothing.
|
|
6
|
+
*/
|
|
7
|
+
export function leaveErrorsToClose(emitter) {
|
|
8
|
+
emitter.on('error', () => { });
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=leave-errors-to-close.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"leave-errors-to-close.js","sourceRoot":"","sources":["../../src/connection/leave-errors-to-close.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAqB;IACtD,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AAChC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-directory-connector.d.ts","sourceRoot":"","sources":["../../src/connection/local-directory-connector.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"local-directory-connector.d.ts","sourceRoot":"","sources":["../../src/connection/local-directory-connector.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAExE;;;;;;GAMG;AACH,qBAAa,uBAAwB,YAAW,eAAe;;gBAIjD,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe;IAKnD,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;CAM1E"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { assertLocalDirectory } from
|
|
1
|
+
import { assertLocalDirectory } from '@zukhruf/fs';
|
|
2
2
|
/**
|
|
3
3
|
* Refuses a flight directory on a network file system before the first
|
|
4
4
|
* connection exists. Every connect asks, but a directory that passed once is
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-directory-connector.js","sourceRoot":"","sources":["../../src/connection/local-directory-connector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"local-directory-connector.js","sourceRoot":"","sources":["../../src/connection/local-directory-connector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAInD;;;;;;GAMG;AACH,MAAM,OAAO,uBAAuB;IACzB,UAAU,CAAS;IACnB,UAAU,CAAkB;IAErC,YAAY,SAAiB,EAAE,SAA0B;QACvD,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAmB;QAC/B,MAAM,CAAC,cAAc,EAAE,CAAC;QACxB,MAAM,oBAAoB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC5C,MAAM,CAAC,cAAc,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;CACF"}
|
|
@@ -3,13 +3,13 @@ import type { Socket } from 'node:net';
|
|
|
3
3
|
import type { Connection, ConnectionEvents } from './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/connection/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/connection/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,iBAAiB,CAAC;AAIpE;;;;;GAKG;AACH,qBAAa,gBAAgB,CAAC,QAAQ,CACpC,SAAQ,YAAY,CAAC,gBAAgB,CACrC,YAAW,UAAU,CAAC,QAAQ,CAAC;;gBAMnB,MAAM,EAAE,MAAM;IAqB1B,IAAI,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAItC,GAAG;IAIH,KAAK;IAIL,KAAK;CAGN"}
|
|
@@ -1,43 +1,41 @@
|
|
|
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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
this.#write = promisify(socket.write).bind(socket);
|
|
20
|
+
// readline removes its own 'error' listener from the socket when the
|
|
21
|
+
// interface closes on the peer's FIN, so an error after that (e.g. a reset
|
|
22
|
+
// after the half-close) needs this listener of the socket's own.
|
|
23
|
+
leaveErrorsToClose(socket);
|
|
24
|
+
const lines = createInterface({ input: socket, crlfDelay: Infinity });
|
|
25
|
+
lines.on('line', (line) => {
|
|
18
26
|
try {
|
|
19
|
-
|
|
20
|
-
if (isIncoming(parsed))
|
|
21
|
-
this.emit('message', parsed);
|
|
22
|
-
else
|
|
23
|
-
this.close();
|
|
27
|
+
this.emit('message', JSON.parse(line));
|
|
24
28
|
}
|
|
25
29
|
catch {
|
|
26
30
|
this.close();
|
|
27
31
|
}
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
});
|
|
33
|
+
// readline re-emits the socket's errors (e.g. EPIPE when the peer died).
|
|
34
|
+
leaveErrorsToClose(lines);
|
|
31
35
|
socket.once('close', () => this.emit('close'));
|
|
32
36
|
}
|
|
33
37
|
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
|
-
});
|
|
38
|
+
return this.#write(jsonLine(message));
|
|
41
39
|
}
|
|
42
40
|
ref() {
|
|
43
41
|
this.#socket.ref();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socket-connection.js","sourceRoot":"","sources":["../../src/connection/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/connection/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,qEAAqE;QACrE,2EAA2E;QAC3E,iEAAiE;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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { FencingToken, TokenSource } from '@zukhruf/
|
|
1
|
+
import type { FencingToken, TokenSource } from '@zukhruf/fencing';
|
|
2
2
|
import type { Connection } from '../connection/connection.ts';
|
|
3
|
-
import type { FlightResponse, Outcome
|
|
3
|
+
import type { FlightResponse, Outcome } from '../protocol/flight-protocol.ts';
|
|
4
4
|
import { Flight } from './flight.ts';
|
|
5
5
|
import type { Party } from './party.ts';
|
|
6
6
|
export interface FlightCoordinatorOptions {
|
|
@@ -21,7 +21,7 @@ export interface FlightCoordinatorOptions {
|
|
|
21
21
|
export declare class FlightCoordinator {
|
|
22
22
|
#private;
|
|
23
23
|
constructor({ tokens, graceWindow }: FlightCoordinatorOptions);
|
|
24
|
-
serve(connection: Connection<FlightResponse
|
|
24
|
+
serve(connection: Connection<FlightResponse>): void;
|
|
25
25
|
run(party: Party, key: string): Promise<void>;
|
|
26
26
|
/** A joiner that lost its connection, back for the flight it joined: it never leads, so its work never runs twice. */
|
|
27
27
|
rejoin(party: Party, key: string, flight: string): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flight-coordinator.d.ts","sourceRoot":"","sources":["../../src/coordinator/flight-coordinator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"flight-coordinator.d.ts","sourceRoot":"","sources":["../../src/coordinator/flight-coordinator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAElE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGxC,MAAM,WAAW,wBAAwB;IACvC,oEAAoE;IACpE,MAAM,EAAE,WAAW,CAAC;IACpB;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAUD;;;;GAIG;AACH,qBAAa,iBAAiB;;gBAGhB,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,wBAAwB;IAgB7D,KAAK,CAAC,UAAU,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,IAAI;IAInD,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7C,sHAAsH;IACtH,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhE,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI;IAI9D,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAI5C,qDAAqD;IACrD,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CAGhC"}
|
|
@@ -57,7 +57,7 @@ class Coordinating {
|
|
|
57
57
|
// A token that goes unused is harmless: tokens only need to grow.
|
|
58
58
|
const token = await this.#tokens.next(key);
|
|
59
59
|
// The client may have withdrawn the run while the token was minted.
|
|
60
|
-
if (party.
|
|
60
|
+
if (!party.waiting)
|
|
61
61
|
return;
|
|
62
62
|
const inProgress = this.#flights.get(key);
|
|
63
63
|
if (inProgress)
|
|
@@ -68,15 +68,15 @@ class Coordinating {
|
|
|
68
68
|
}
|
|
69
69
|
/** A rejoin joins only its own flight; any other answer could be a second run of the work. */
|
|
70
70
|
async rejoin(party, key, flight) {
|
|
71
|
-
if (party.
|
|
71
|
+
if (!party.waiting)
|
|
72
72
|
return;
|
|
73
73
|
const inProgress = this.#flights.get(key);
|
|
74
74
|
if (inProgress?.is(flight))
|
|
75
75
|
return inProgress.add(party);
|
|
76
|
-
party.end({ op: 'interrupted'
|
|
76
|
+
party.end({ op: 'interrupted' });
|
|
77
77
|
}
|
|
78
78
|
reassert(party) {
|
|
79
|
-
party.end({ op: 'rejected'
|
|
79
|
+
party.end({ op: 'rejected' });
|
|
80
80
|
}
|
|
81
81
|
land(flight, outcome) {
|
|
82
82
|
this.#forget(flight);
|
|
@@ -118,16 +118,16 @@ class GraceWindow {
|
|
|
118
118
|
async rejoin(party, key, flight) {
|
|
119
119
|
const over = this.#over.wait().then(() => 'over');
|
|
120
120
|
for (;;) {
|
|
121
|
-
if (party.
|
|
121
|
+
if (!party.waiting)
|
|
122
122
|
return;
|
|
123
123
|
const inProgress = this.#flights.get(key);
|
|
124
124
|
if (inProgress?.is(flight))
|
|
125
125
|
return inProgress.add(party);
|
|
126
126
|
const ending = this.#endings.get(key);
|
|
127
|
-
if (ending?.
|
|
127
|
+
if (ending?.flight.is(flight)) {
|
|
128
128
|
return party.end('landed' in ending
|
|
129
|
-
? { op: 'landed',
|
|
130
|
-
: { op: 'interrupted'
|
|
129
|
+
? { op: 'landed', outcome: ending.landed }
|
|
130
|
+
: { op: 'interrupted' });
|
|
131
131
|
}
|
|
132
132
|
const woken = await Promise.race([over, this.#reassertionOf(key)]);
|
|
133
133
|
if (woken === 'over')
|
|
@@ -138,10 +138,10 @@ class GraceWindow {
|
|
|
138
138
|
reassert(party, key, token) {
|
|
139
139
|
const claimed = this.#flights.get(key);
|
|
140
140
|
if (claimed && !token.isNewerThan(claimed.token)) {
|
|
141
|
-
return party.end({ op: 'rejected'
|
|
141
|
+
return party.end({ op: 'rejected' });
|
|
142
142
|
}
|
|
143
143
|
if (claimed) {
|
|
144
|
-
claimed.leader.end({ op: 'rejected'
|
|
144
|
+
claimed.leader.end({ op: 'rejected' });
|
|
145
145
|
this.interrupt(claimed);
|
|
146
146
|
}
|
|
147
147
|
const flight = new Flight(key, token, party);
|
|
@@ -153,17 +153,11 @@ class GraceWindow {
|
|
|
153
153
|
wake();
|
|
154
154
|
}
|
|
155
155
|
land(flight, outcome) {
|
|
156
|
-
this.#endings.set(flight.key, {
|
|
157
|
-
token: flight.token.toString(),
|
|
158
|
-
landed: outcome,
|
|
159
|
-
});
|
|
156
|
+
this.#endings.set(flight.key, { flight, landed: outcome });
|
|
160
157
|
this.#next.land(flight, outcome);
|
|
161
158
|
}
|
|
162
159
|
interrupt(flight) {
|
|
163
|
-
this.#endings.set(flight.key, {
|
|
164
|
-
token: flight.token.toString(),
|
|
165
|
-
interrupted: true,
|
|
166
|
-
});
|
|
160
|
+
this.#endings.set(flight.key, { flight, interrupted: true });
|
|
167
161
|
this.#next.interrupt(flight);
|
|
168
162
|
}
|
|
169
163
|
#reassertionOf(key) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flight-coordinator.js","sourceRoot":"","sources":["../../src/coordinator/flight-coordinator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"flight-coordinator.js","sourceRoot":"","sources":["../../src/coordinator/flight-coordinator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Term } from '@zukhruf/election';
|
|
2
2
|
export interface FlightServerOptions {
|
|
3
3
|
/** Milliseconds the new term starts no flight, so leaders from the last term can reassert theirs. */
|
|
4
4
|
graceWindow: number;
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
7
7
|
* Serves a `FlightCoordinator` on a Unix socket for one term. Lease tokens
|
|
8
|
-
* carry the term's epoch, so they outrank every token of earlier terms.
|
|
8
|
+
* carry the term's epoch, so they outrank every token of earlier terms. A
|
|
9
|
+
* term that is lost may already be another process's, so the server closes
|
|
10
|
+
* itself when the term's signal aborts.
|
|
9
11
|
*/
|
|
10
12
|
export declare class FlightServer {
|
|
11
13
|
#private;
|
|
12
14
|
private constructor();
|
|
13
|
-
static start(socketPath: string,
|
|
15
|
+
static start(socketPath: string, term: Term, { graceWindow }: FlightServerOptions): Promise<FlightServer>;
|
|
14
16
|
/**
|
|
15
17
|
* Hands the term over. Ending every connection tells the other processes to
|
|
16
18
|
* elect a successor and reassert their flights during its grace window;
|
|
@@ -18,6 +20,8 @@ export declare class FlightServer {
|
|
|
18
20
|
* Each connection ends only after what was written to it, such as an
|
|
19
21
|
* outcome for a joiner, is sent. The term ends only after the socket is
|
|
20
22
|
* gone: in the other order, this close could remove a successor's socket file.
|
|
23
|
+
* The first call removes the file at once, so a second caller finds it gone,
|
|
24
|
+
* and it too resolves only once the term ended.
|
|
21
25
|
*/
|
|
22
26
|
close(): Promise<void>;
|
|
23
27
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flight-server.d.ts","sourceRoot":"","sources":["../../src/coordinator/flight-server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"flight-server.d.ts","sourceRoot":"","sources":["../../src/coordinator/flight-server.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAQ9C,MAAM,WAAW,mBAAmB;IAClC,qGAAqG;IACrG,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,qBAAa,YAAY;;IAMvB,OAAO;WAOM,KAAK,CAChB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,IAAI,EACV,EAAE,WAAW,EAAE,EAAE,mBAAmB,GACnC,OAAO,CAAC,YAAY,CAAC;IAkCxB;;;;;;;;;OASG;IACG,KAAK;CAOZ"}
|
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { addAbortListener, once } from 'node:events';
|
|
2
|
+
import { rm } from 'node:fs/promises';
|
|
2
3
|
import { createServer } from 'node:net';
|
|
3
|
-
import { EpochTokenSource } from '@zukhruf/
|
|
4
|
+
import { EpochTokenSource } from '@zukhruf/fencing';
|
|
4
5
|
import { welcome } from "../connection/handshake.js";
|
|
5
6
|
import { SocketConnection } from "../connection/socket-connection.js";
|
|
6
|
-
import { isRequestEnvelope, } from "../protocol/flight-protocol.js";
|
|
7
|
-
import { isErrno } from "../shared/fs/errno.js";
|
|
8
7
|
import { FlightCoordinator } from "./flight-coordinator.js";
|
|
9
8
|
/**
|
|
10
9
|
* Serves a `FlightCoordinator` on a Unix socket for one term. Lease tokens
|
|
11
|
-
* carry the term's epoch, so they outrank every token of earlier terms.
|
|
10
|
+
* carry the term's epoch, so they outrank every token of earlier terms. A
|
|
11
|
+
* term that is lost may already be another process's, so the server closes
|
|
12
|
+
* itself when the term's signal aborts.
|
|
12
13
|
*/
|
|
13
14
|
export class FlightServer {
|
|
14
15
|
#server;
|
|
15
16
|
#connections;
|
|
16
|
-
#
|
|
17
|
-
|
|
17
|
+
#term;
|
|
18
|
+
#closeOnLoss;
|
|
19
|
+
constructor(server, connections, term) {
|
|
18
20
|
this.#server = server;
|
|
19
21
|
this.#connections = connections;
|
|
20
|
-
this.#
|
|
22
|
+
this.#term = term;
|
|
23
|
+
this.#closeOnLoss = addAbortListener(term.signal, () => void this.close());
|
|
21
24
|
}
|
|
22
|
-
static async start(socketPath,
|
|
25
|
+
static async start(socketPath, term, { graceWindow }) {
|
|
23
26
|
// Only the coordinator gets here, so removing a dead coordinator's socket file cannot race another server.
|
|
24
27
|
// Windows removes a named pipe when its process stops, so there is no file to remove.
|
|
25
28
|
if (process.platform !== 'win32') {
|
|
26
|
-
await
|
|
27
|
-
if (!isErrno(error, 'ENOENT'))
|
|
28
|
-
throw error;
|
|
29
|
-
});
|
|
29
|
+
await rm(socketPath, { force: true });
|
|
30
30
|
}
|
|
31
31
|
const coordinator = new FlightCoordinator({
|
|
32
|
-
tokens: new EpochTokenSource(
|
|
32
|
+
tokens: new EpochTokenSource(term.epoch),
|
|
33
33
|
graceWindow,
|
|
34
34
|
});
|
|
35
35
|
const connections = new Set();
|
|
@@ -42,18 +42,19 @@ export class FlightServer {
|
|
|
42
42
|
void welcome(socket).then((speaksOurs) => {
|
|
43
43
|
if (!speaksOurs)
|
|
44
44
|
return;
|
|
45
|
-
coordinator.serve(new SocketConnection(socket
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
await new Promise((resolve, reject) => {
|
|
49
|
-
server.once('error', reject);
|
|
50
|
-
server.listen(socketPath, () => {
|
|
51
|
-
server.off('error', reject);
|
|
52
|
-
resolve();
|
|
45
|
+
coordinator.serve(new SocketConnection(socket));
|
|
53
46
|
});
|
|
54
47
|
});
|
|
48
|
+
server.listen(socketPath);
|
|
49
|
+
await once(server, 'listening');
|
|
55
50
|
server.unref();
|
|
56
|
-
|
|
51
|
+
const started = new FlightServer(server, connections, term);
|
|
52
|
+
// The term may have been lost while the server started.
|
|
53
|
+
if (term.signal.aborted) {
|
|
54
|
+
await started.close();
|
|
55
|
+
term.signal.throwIfAborted();
|
|
56
|
+
}
|
|
57
|
+
return started;
|
|
57
58
|
}
|
|
58
59
|
/**
|
|
59
60
|
* Hands the term over. Ending every connection tells the other processes to
|
|
@@ -62,13 +63,16 @@ export class FlightServer {
|
|
|
62
63
|
* Each connection ends only after what was written to it, such as an
|
|
63
64
|
* outcome for a joiner, is sent. The term ends only after the socket is
|
|
64
65
|
* gone: in the other order, this close could remove a successor's socket file.
|
|
66
|
+
* The first call removes the file at once, so a second caller finds it gone,
|
|
67
|
+
* and it too resolves only once the term ended.
|
|
65
68
|
*/
|
|
66
69
|
async close() {
|
|
67
|
-
|
|
70
|
+
this.#closeOnLoss[Symbol.dispose]();
|
|
71
|
+
const closed = this.#server[Symbol.asyncDispose]();
|
|
68
72
|
for (const socket of this.#connections)
|
|
69
73
|
socket.destroySoon();
|
|
70
74
|
await closed;
|
|
71
|
-
await this.#
|
|
75
|
+
await this.#term.resign();
|
|
72
76
|
}
|
|
73
77
|
}
|
|
74
78
|
//# sourceMappingURL=flight-server.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flight-server.js","sourceRoot":"","sources":["../../src/coordinator/flight-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"flight-server.js","sourceRoot":"","sources":["../../src/coordinator/flight-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FencingToken } from '@zukhruf/
|
|
1
|
+
import type { FencingToken } from '@zukhruf/fencing';
|
|
2
2
|
import type { Outcome } from '../protocol/flight-protocol.ts';
|
|
3
3
|
import type { Party } from './party.ts';
|
|
4
4
|
/** A flight in progress: the key, the leader that runs the work, its lease token, and the parties that joined. */
|
|
@@ -8,7 +8,9 @@ export declare class Flight {
|
|
|
8
8
|
readonly token: FencingToken;
|
|
9
9
|
readonly leader: Party;
|
|
10
10
|
constructor(key: string, token: FencingToken, leader: Party);
|
|
11
|
-
/**
|
|
11
|
+
/** The flight's name on the wire: its token as decimal text, which a joined answer and a rejoin carry. */
|
|
12
|
+
get id(): string;
|
|
13
|
+
/** Whether this is the flight with the id `flight`, which a rejoin names. */
|
|
12
14
|
is(flight: string): boolean;
|
|
13
15
|
add(joiner: Party): void;
|
|
14
16
|
remove(joiner: Party): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flight.d.ts","sourceRoot":"","sources":["../../src/coordinator/flight.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"flight.d.ts","sourceRoot":"","sources":["../../src/coordinator/flight.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,kHAAkH;AAClH,qBAAa,MAAM;;IACjB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;gBAGX,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK;IAM3D,0GAA0G;IAC1G,IAAI,EAAE,IAAI,MAAM,CAEf;IAED,6EAA6E;IAC7E,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAI3B,GAAG,CAAC,MAAM,EAAE,KAAK;IAKjB,MAAM,CAAC,MAAM,EAAE,KAAK;IAIpB,yFAAyF;IACzF,IAAI,CAAC,OAAO,EAAE,OAAO;IAQrB,0GAA0G;IAC1G,SAAS;CAMV"}
|
|
@@ -9,9 +9,13 @@ export class Flight {
|
|
|
9
9
|
this.token = token;
|
|
10
10
|
this.leader = leader;
|
|
11
11
|
}
|
|
12
|
-
/**
|
|
12
|
+
/** The flight's name on the wire: its token as decimal text, which a joined answer and a rejoin carry. */
|
|
13
|
+
get id() {
|
|
14
|
+
return this.token.toString();
|
|
15
|
+
}
|
|
16
|
+
/** Whether this is the flight with the id `flight`, which a rejoin names. */
|
|
13
17
|
is(flight) {
|
|
14
|
-
return flight === this.
|
|
18
|
+
return flight === this.id;
|
|
15
19
|
}
|
|
16
20
|
add(joiner) {
|
|
17
21
|
this.#joiners.add(joiner);
|
|
@@ -23,15 +27,15 @@ export class Flight {
|
|
|
23
27
|
/** Pushes the outcome to every joiner, then tells the leader that it was handed over. */
|
|
24
28
|
land(outcome) {
|
|
25
29
|
for (const joiner of this.#joiners) {
|
|
26
|
-
joiner.end({ op: 'landed',
|
|
30
|
+
joiner.end({ op: 'landed', outcome });
|
|
27
31
|
}
|
|
28
32
|
this.#joiners.clear();
|
|
29
|
-
this.leader.end({ op: 'ack'
|
|
33
|
+
this.leader.end({ op: 'ack' });
|
|
30
34
|
}
|
|
31
35
|
/** Ends without an outcome: every joiner learns that its flight is lost, and none runs the work again. */
|
|
32
36
|
interrupt() {
|
|
33
37
|
for (const joiner of this.#joiners) {
|
|
34
|
-
joiner.end({ op: 'interrupted'
|
|
38
|
+
joiner.end({ op: 'interrupted' });
|
|
35
39
|
}
|
|
36
40
|
this.#joiners.clear();
|
|
37
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flight.js","sourceRoot":"","sources":["../../src/coordinator/flight.ts"],"names":[],"mappings":"AAKA,kHAAkH;AAClH,MAAM,OAAO,MAAM;IACR,GAAG,CAAS;IACZ,KAAK,CAAe;IACpB,MAAM,CAAQ;IACd,QAAQ,GAAG,IAAI,GAAG,EAAS,CAAC;IAErC,YAAY,GAAW,EAAE,KAAmB,EAAE,MAAa;QACzD,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,
|
|
1
|
+
{"version":3,"file":"flight.js","sourceRoot":"","sources":["../../src/coordinator/flight.ts"],"names":[],"mappings":"AAKA,kHAAkH;AAClH,MAAM,OAAO,MAAM;IACR,GAAG,CAAS;IACZ,KAAK,CAAe;IACpB,MAAM,CAAQ;IACd,QAAQ,GAAG,IAAI,GAAG,EAAS,CAAC;IAErC,YAAY,GAAW,EAAE,KAAmB,EAAE,MAAa;QACzD,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,0GAA0G;IAC1G,IAAI,EAAE;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC/B,CAAC;IAED,6EAA6E;IAC7E,EAAE,CAAC,MAAc;QACf,OAAO,MAAM,KAAK,IAAI,CAAC,EAAE,CAAC;IAC5B,CAAC;IAED,GAAG,CAAC,MAAa;QACf,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,CAAC,MAAa;QAClB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;IAED,yFAAyF;IACzF,IAAI,CAAC,OAAgB;QACnB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACjC,CAAC;IAED,0GAA0G;IAC1G,SAAS;QACP,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,aAAa,EAAE,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;CACF"}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { FlightResponse } from '../protocol/flight-protocol.ts';
|
|
2
2
|
import type { Flight } from './flight.ts';
|
|
3
|
+
/** A response to one party, without the id: the party fills in its own. */
|
|
4
|
+
type Answer = {
|
|
5
|
+
[Op in FlightResponse['op']]: Omit<Extract<FlightResponse, {
|
|
6
|
+
op: Op;
|
|
7
|
+
}>, 'id'>;
|
|
8
|
+
}[FlightResponse['op']];
|
|
3
9
|
/** Where a party's answers go: the session of the party's connection. */
|
|
4
10
|
export interface Inbox {
|
|
5
11
|
reply(response: FlightResponse): void;
|
|
@@ -28,11 +34,14 @@ export declare class Party {
|
|
|
28
34
|
readonly id: string;
|
|
29
35
|
constructor(id: string, inbox: Inbox);
|
|
30
36
|
get role(): Role;
|
|
37
|
+
/** Whether the party still waits: it has no answer yet, it was not withdrawn, and its connection is not gone. */
|
|
38
|
+
get waiting(): boolean;
|
|
31
39
|
lead(flight: Flight): void;
|
|
32
40
|
/** A leader from before a failover claimed its flight again; it already knows that it leads. */
|
|
33
41
|
resume(flight: Flight): void;
|
|
34
42
|
join(flight: Flight): void;
|
|
35
|
-
/** Answers for good with `
|
|
36
|
-
end(
|
|
43
|
+
/** Answers for good with `answer`, or ends without an answer when it was withdrawn or its connection is gone. */
|
|
44
|
+
end(answer?: Answer): void;
|
|
37
45
|
}
|
|
46
|
+
export {};
|
|
38
47
|
//# sourceMappingURL=party.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"party.d.ts","sourceRoot":"","sources":["../../src/coordinator/party.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,yEAAyE;AACzE,MAAM,WAAW,KAAK;IACpB,KAAK,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,gFAAgF;IAChF,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,8CAA8C;AAC9C,MAAM,MAAM,IAAI;AACd,wFAAwF;AACtF;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AACrC,+DAA+D;GAC7D;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErB,sHAAsH;AACtH,qBAAa,KAAK;;IAChB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;gBAIR,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK;IAKpC,IAAI,IAAI,IAAI,IAAI,CAEf;IAED,IAAI,CAAC,MAAM,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"party.d.ts","sourceRoot":"","sources":["../../src/coordinator/party.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,2EAA2E;AAC3E,KAAK,MAAM,GAAG;KACX,EAAE,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE;QAAE,EAAE,EAAE,EAAE,CAAA;KAAE,CAAC,EAAE,IAAI,CAAC;CAC9E,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;AAExB,yEAAyE;AACzE,MAAM,WAAW,KAAK;IACpB,KAAK,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,gFAAgF;IAChF,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,8CAA8C;AAC9C,MAAM,MAAM,IAAI;AACd,wFAAwF;AACtF;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AACrC,+DAA+D;GAC7D;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErB,sHAAsH;AACtH,qBAAa,KAAK;;IAChB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;gBAIR,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK;IAKpC,IAAI,IAAI,IAAI,IAAI,CAEf;IAED,iHAAiH;IACjH,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,IAAI,CAAC,MAAM,EAAE,MAAM;IAKnB,gGAAgG;IAChG,MAAM,CAAC,MAAM,EAAE,MAAM;IAIrB,IAAI,CAAC,MAAM,EAAE,MAAM;IAKnB,iHAAiH;IACjH,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM;CAWpB"}
|