@zukhruf/single-flight 0.3.17 → 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 +5 -5
- package/dist/client/flight-client.d.ts +2 -2
- package/dist/client/flight-client.d.ts.map +1 -1
- package/dist/client/flight-client.js +6 -1
- 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/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 +2 -2
- 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 +28 -24
- package/dist/coordinator/flight-server.js.map +1 -1
- package/dist/coordinator/flight.d.ts +3 -1
- 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 +7 -2
- package/dist/coordinator/session.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 +15 -9
- package/dist/protocol/flight-protocol.js.map +1 -1
- package/dist/single-flight.d.ts.map +1 -1
- package/dist/single-flight.js +5 -7
- package/dist/single-flight.js.map +1 -1
- package/package.json +2 -1
- 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 -78
- 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/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":"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
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,kBAAkB,CAAC;AAElE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,
|
|
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
4
|
import { EpochTokenSource } from '@zukhruf/fencing';
|
|
4
|
-
import { isErrno } from '@zukhruf/fs';
|
|
5
5
|
import { welcome } from "../connection/handshake.js";
|
|
6
6
|
import { SocketConnection } from "../connection/socket-connection.js";
|
|
7
|
-
import { isRequestEnvelope, } from "../protocol/flight-protocol.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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"}
|
|
@@ -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,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,
|
|
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"}
|
|
@@ -10,13 +10,13 @@ export class Party {
|
|
|
10
10
|
get role() {
|
|
11
11
|
return this.#role;
|
|
12
12
|
}
|
|
13
|
+
/** Whether the party still waits: it has no answer yet, it was not withdrawn, and its connection is not gone. */
|
|
14
|
+
get waiting() {
|
|
15
|
+
return this.#role.kind === 'waiting';
|
|
16
|
+
}
|
|
13
17
|
lead(flight) {
|
|
14
18
|
this.#role = { kind: 'leading', flight };
|
|
15
|
-
this.#
|
|
16
|
-
op: 'lead',
|
|
17
|
-
id: this.id,
|
|
18
|
-
token: flight.token.toString(),
|
|
19
|
-
});
|
|
19
|
+
this.#reply({ op: 'lead', token: flight.token.toString() });
|
|
20
20
|
}
|
|
21
21
|
/** A leader from before a failover claimed its flight again; it already knows that it leads. */
|
|
22
22
|
resume(flight) {
|
|
@@ -24,20 +24,20 @@ export class Party {
|
|
|
24
24
|
}
|
|
25
25
|
join(flight) {
|
|
26
26
|
this.#role = { kind: 'joining', flight };
|
|
27
|
-
this.#
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
/** Answers for good with `response`, or ends without an answer when it was withdrawn or its connection is gone. */
|
|
34
|
-
end(response) {
|
|
27
|
+
this.#reply({ op: 'joined', flight: flight.id });
|
|
28
|
+
}
|
|
29
|
+
/** Answers for good with `answer`, or ends without an answer when it was withdrawn or its connection is gone. */
|
|
30
|
+
end(answer) {
|
|
35
31
|
if (this.#role.kind === 'gone')
|
|
36
32
|
return;
|
|
37
33
|
this.#role = { kind: 'gone' };
|
|
38
34
|
this.#inbox.forget(this.id);
|
|
39
|
-
if (
|
|
40
|
-
this.#
|
|
35
|
+
if (answer)
|
|
36
|
+
this.#reply(answer);
|
|
37
|
+
}
|
|
38
|
+
#reply(answer) {
|
|
39
|
+
// The id goes right after the op, so each line keeps its bytes: op, id, then the fields of the op.
|
|
40
|
+
this.#inbox.reply(Object.assign({ op: answer.op, id: this.id }, answer));
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
//# sourceMappingURL=party.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"party.js","sourceRoot":"","sources":["../../src/coordinator/party.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"party.js","sourceRoot":"","sources":["../../src/coordinator/party.ts"],"names":[],"mappings":"AAwBA,sHAAsH;AACtH,MAAM,OAAO,KAAK;IACP,EAAE,CAAS;IACX,MAAM,CAAQ;IACvB,KAAK,GAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAElC,YAAY,EAAU,EAAE,KAAY;QAClC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,iHAAiH;IACjH,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC;IACvC,CAAC;IAED,IAAI,CAAC,MAAc;QACjB,IAAI,CAAC,KAAK,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;QACzC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,gGAAgG;IAChG,MAAM,CAAC,MAAc;QACnB,IAAI,CAAC,KAAK,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAC3C,CAAC;IAED,IAAI,CAAC,MAAc;QACjB,IAAI,CAAC,KAAK,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;QACzC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,iHAAiH;IACjH,GAAG,CAAC,MAAe;QACjB,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO;QACvC,IAAI,CAAC,KAAK,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC5B,IAAI,MAAM;YAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAED,MAAM,CAAC,MAAc;QACnB,mGAAmG;QACnG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3E,CAAC;CACF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Connection } from '../connection/connection.ts';
|
|
2
|
-
import { type FlightResponse
|
|
2
|
+
import { type FlightResponse } from '../protocol/flight-protocol.ts';
|
|
3
3
|
import type { FlightCoordinator } from './flight-coordinator.ts';
|
|
4
4
|
import { type Inbox } from './party.ts';
|
|
5
5
|
/**
|
|
@@ -9,7 +9,7 @@ import { type Inbox } from './party.ts';
|
|
|
9
9
|
*/
|
|
10
10
|
export declare class Session implements Inbox {
|
|
11
11
|
#private;
|
|
12
|
-
constructor(coordinator: FlightCoordinator, connection: Connection<FlightResponse
|
|
12
|
+
constructor(coordinator: FlightCoordinator, connection: Connection<FlightResponse>);
|
|
13
13
|
reply(response: FlightResponse): void;
|
|
14
14
|
forget(id: string): void;
|
|
15
15
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/coordinator/session.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EACL,KAAK,cAAc,
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/coordinator/session.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EACL,KAAK,cAAc,EAIpB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,KAAK,KAAK,EAAS,MAAM,YAAY,CAAC;AAE/C;;;;GAIG;AACH,qBAAa,OAAQ,YAAW,KAAK;;gBAMjC,WAAW,EAAE,iBAAiB,EAC9B,UAAU,EAAE,UAAU,CAAC,cAAc,CAAC;IAYxC,KAAK,CAAC,QAAQ,EAAE,cAAc;IAI9B,MAAM,CAAC,EAAE,EAAE,MAAM;CAgElB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FencingToken } from '@zukhruf/fencing';
|
|
2
|
-
import { isFlightRequest, } from "../protocol/flight-protocol.js";
|
|
2
|
+
import { isFlightRequest, isRequestEnvelope, } from "../protocol/flight-protocol.js";
|
|
3
3
|
import { Party } from "./party.js";
|
|
4
4
|
/**
|
|
5
5
|
* One client connection. It turns each request into a party of the
|
|
@@ -13,7 +13,12 @@ export class Session {
|
|
|
13
13
|
constructor(coordinator, connection) {
|
|
14
14
|
this.#coordinator = coordinator;
|
|
15
15
|
this.#phase = new Serving(connection);
|
|
16
|
-
connection.on('message', (
|
|
16
|
+
connection.on('message', (message) => {
|
|
17
|
+
// A message with no op or no id cannot be answered, so it is ignored, and the peer keeps its flights (ADR 0008).
|
|
18
|
+
if (!isRequestEnvelope(message))
|
|
19
|
+
return;
|
|
20
|
+
this.#handle(message);
|
|
21
|
+
});
|
|
17
22
|
connection.once('close', () => this.#end());
|
|
18
23
|
}
|
|
19
24
|
reply(response) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/coordinator/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhD,OAAO,EAGL,eAAe,
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/coordinator/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -88,7 +88,11 @@ export interface RequestEnvelope {
|
|
|
88
88
|
id: string;
|
|
89
89
|
}
|
|
90
90
|
export declare function isRequestEnvelope(message: unknown): message is RequestEnvelope;
|
|
91
|
-
/**
|
|
92
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Messages arrive from another process, so their shape is checked before
|
|
93
|
+
* use. `isRequestEnvelope` already checked the `op` and the `id`, so only the
|
|
94
|
+
* fields of each request are left.
|
|
95
|
+
*/
|
|
96
|
+
export declare function isFlightRequest(request: RequestEnvelope): request is FlightRequest;
|
|
93
97
|
export declare function isFlightResponse(message: unknown): message is FlightResponse;
|
|
94
98
|
//# sourceMappingURL=flight-protocol.d.ts.map
|