@zukhruf/single-flight 0.3.20 → 0.3.21

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.
Files changed (41) hide show
  1. package/README.md +26 -17
  2. package/dist/client/flight-client.d.ts +9 -1
  3. package/dist/client/flight-client.d.ts.map +1 -1
  4. package/dist/client/flight-client.js +86 -16
  5. package/dist/client/flight-client.js.map +1 -1
  6. package/dist/coordinator/flight-coordinator.d.ts +24 -12
  7. package/dist/coordinator/flight-coordinator.d.ts.map +1 -1
  8. package/dist/coordinator/flight-coordinator.js +92 -143
  9. package/dist/coordinator/flight-coordinator.js.map +1 -1
  10. package/dist/coordinator/flight-server.d.ts +7 -7
  11. package/dist/coordinator/flight-server.d.ts.map +1 -1
  12. package/dist/coordinator/flight-server.js +7 -13
  13. package/dist/coordinator/flight-server.js.map +1 -1
  14. package/dist/coordinator/flight.d.ts +13 -2
  15. package/dist/coordinator/flight.d.ts.map +1 -1
  16. package/dist/coordinator/flight.js +20 -4
  17. package/dist/coordinator/flight.js.map +1 -1
  18. package/dist/coordinator/parked-runs.d.ts +26 -0
  19. package/dist/coordinator/parked-runs.d.ts.map +1 -0
  20. package/dist/coordinator/parked-runs.js +65 -0
  21. package/dist/coordinator/parked-runs.js.map +1 -0
  22. package/dist/coordinator/party.d.ts +1 -1
  23. package/dist/coordinator/party.d.ts.map +1 -1
  24. package/dist/coordinator/session.d.ts.map +1 -1
  25. package/dist/coordinator/session.js +6 -3
  26. package/dist/coordinator/session.js.map +1 -1
  27. package/dist/key-lock/key-hold.d.ts +16 -0
  28. package/dist/key-lock/key-hold.d.ts.map +1 -0
  29. package/dist/key-lock/key-hold.js +24 -0
  30. package/dist/key-lock/key-hold.js.map +1 -0
  31. package/dist/key-lock/key-locks.d.ts +35 -0
  32. package/dist/key-lock/key-locks.d.ts.map +1 -0
  33. package/dist/key-lock/key-locks.js +67 -0
  34. package/dist/key-lock/key-locks.js.map +1 -0
  35. package/dist/protocol/flight-protocol.d.ts +2 -2
  36. package/dist/protocol/flight-protocol.d.ts.map +1 -1
  37. package/dist/single-flight.d.ts +4 -12
  38. package/dist/single-flight.d.ts.map +1 -1
  39. package/dist/single-flight.js +36 -29
  40. package/dist/single-flight.js.map +1 -1
  41. package/package.json +7 -8
package/README.md CHANGED
@@ -70,7 +70,7 @@ The lease that the work gets comes from `@zukhruf/lease`, and its token comes fr
70
70
 
71
71
  ## The directory
72
72
 
73
- The directory is the local folder where the processes that share flights meet. Each process that uses a `SingleFlight` keeps four files there: `flight.lock`, `flight.epoch`, `flight.lock.clean` and `flight.sock`. The election of [`@zukhruf/election`](../election/README.md) claims `flight.lock` with a file lock, and records the epoch of the last term in `flight.epoch`. After a clean shutdown of a coordinator, `flight.lock.clean` holds the epoch of its term until the next term starts. The journal of the claim is in memory, so a coordinator that stops leaves no `flight.lock-journal` file. All the processes that name the same directory are one group, and the callers of one key share a flight in that group only.
73
+ The directory is the local folder where the processes that share flights meet. Each process that uses a `SingleFlight` keeps three files and a folder there: `flight.lock`, `flight.epoch`, `flight.sock` and `execution-locks/`. The election of [`@zukhruf/election`](../election/README.md) claims `flight.lock` with a file lock, and records the epoch of the last term in `flight.epoch`. The folder `execution-locks/` has one file for each key that ever led: the key lock of that key, named by the SHA-256 of the key. The process that runs the work of a key holds a file lock on that file (see [When a process stops](#when-a-process-stops)). The files stay after the flights, so do not remove them while a process uses the directory. The journal of the claim is in memory, so a coordinator that stops leaves no `flight.lock-journal` file. All the processes that name the same directory are one group, and the callers of one key share a flight in that group only.
74
74
 
75
75
  There is no default directory. One default would put each application on the host into one group, and unrelated applications that use the same key would join each other's flights. Give each group its own directory, for example a folder of your application's data.
76
76
 
@@ -87,15 +87,14 @@ All the processes of the directory take part in one election. The winner is the
87
87
  The work gets the lease of the flight:
88
88
 
89
89
  - `token`: a `FencingToken`. Its high 32 bits are the epoch of the coordinator's term, so a newer term always gives higher tokens.
90
- - `signal`: it aborts with `LeaseLostError` when the flight is no longer the leader's. The `subject` of the error is the key. This occurs when the leader misses the grace window of a new coordinator.
90
+ - `signal`: it aborts with `LeaseLostError` when the flight is no longer the leader's, so its outcome reaches no joiner. The `subject` of the error is the key. This occurs when a new coordinator refuses the reassert of the leader, because it knows a newer flight of the key, or when this process cannot connect to a coordinator again.
91
91
 
92
- | Option | What it does |
93
- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
94
- | `directory` | The local folder where the processes of one group meet. See [The directory](#the-directory). |
95
- | `codec` | Turns the value of a flight into text for the joiners, and back. See [The codec](#the-codec). |
96
- | `graceWindow` | Milliseconds that a new coordinator starts no flight, so the leaders of the flights in progress can reassert them. It must be longer than a process takes to connect again. A coordinator after a clean shutdown has none. Defaults to `500`. |
92
+ | Option | What it does |
93
+ | ----------- | --------------------------------------------------------------------------------------------- |
94
+ | `directory` | The local folder where the processes of one group meet. See [The directory](#the-directory). |
95
+ | `codec` | Turns the value of a flight into text for the joiners, and back. See [The codec](#the-codec). |
97
96
 
98
- `flights[Symbol.asyncDispose]()` waits until each landing of this process reached a coordinator, and then it disconnects. When this process is the coordinator, the other processes elect a new one.
97
+ `flights[Symbol.asyncDispose]()` waits until each landing of this process reached a coordinator, and then it disconnects. When this process is the coordinator, the other processes elect a new one. The work of a flight that this process leads continues, and this process keeps the key lock of that key until the work ends.
99
98
 
100
99
  ## The codec
101
100
 
@@ -165,17 +164,26 @@ Give a signal to stop the wait of one caller: `flights.run(key, work, { signal:
165
164
 
166
165
  ## When a process stops
167
166
 
168
- - **The process of a leader stops.** The coordinator tells each joiner that the flight is interrupted, and each joiner rejects with `FlightInterruptedError` at once. No joiner runs the work again. The next call of the key leads a new flight.
169
- - **The coordinator disposes with nothing in progress.** This is a clean shutdown: no flight is in progress, and the grace window of the coordinator is over, or it had none. The next coordinator then has no grace window, and each call leads or joins at once. [ADR 0009](./docs/adr/0009-the-next-coordinator-skips-the-grace-window-after-a-clean-shutdown.md) tells why.
170
- - **The coordinator stops in another way.** For example, its process stops, or it disposes while a flight is in progress. The other processes elect a new coordinator. Its term starts with a grace window. In the grace window:
167
+ A leader keeps its flight while its process lives. Before its work starts, the leader takes a kernel lock on its key, the key lock. It frees the key lock only when its work settled and its flight needs nothing more from it: the coordinator acknowledged its landing, its lease was lost, or its `SingleFlight` closed. The kernel keeps the key lock while the process lives, also while the process is frozen, and it frees the key lock when the process dies. Thus no other process starts the work of the key beside it. [ADR 0010](./docs/adr/0010-a-leader-holds-a-kernel-lock-on-its-key-until-its-outcome-is-handed-over.md) tells why.
168
+
169
+ - **The process of a leader stops.** The coordinator tells each joiner that the flight is interrupted, and each joiner rejects with `FlightInterruptedError` at once. No joiner runs the work again. The kernel frees the key lock, and the next call of the key leads a new flight.
170
+ - **A leader disposes its `SingleFlight` while its work runs.** The coordinator interrupts the flight, because a disposed leader cannot send its outcome. Each joiner rejects with `FlightInterruptedError`. The work continues, and the leader keeps the key lock until the work ends. A call of the key in another process waits until then, and then it leads a new flight.
171
+ - **The coordinator stops or disposes.** The other processes elect a new coordinator, and it answers at once:
171
172
  - Each leader reasserts its flight, and sends its landing again when it has one.
172
173
  - Each joiner rejoins its flight by the flight's token, and it gets the outcome of that flight.
173
- - A new call waits for the grace window to end. Then it leads or joins.
174
- - **A leader misses the grace window**, for example because its process was frozen. Its lease is lost: the signal of the lease aborts with `LeaseLostError`, and its call rejects with that error. When the work throws its own error after the loss, the call rejects with a new `LeaseLostError`, and the error of the work is its `cause`. Thus `LeaseLostError` always tells the leader that its work did not run alone. Its joiners get `FlightInterruptedError`. [ADR 0007](./docs/adr/0007-a-work-error-after-a-lost-lease-rejects-with-leaselosterror.md) tells why.
175
- - **A joiner's leader and the coordinator stop together.** The joiner gets `FlightInterruptedError` at the end of the grace window. It never runs the work again.
174
+ - A new call of a key that no process holds leads or joins at once.
175
+ - A new call or a rejoin of a key whose key lock another process holds, while the new coordinator knows no flight of the key, waits. When the leader reasserts its flight, the call or the rejoin joins it. When the key lock frees first, the call leads, and the rejoin gets `FlightInterruptedError`.
176
+ - **A leader is frozen or busy, for example stopped by a debugger or in a long synchronous step.** It keeps its flight and its key lock. When the coordinator stops in that time, the calls of the key wait. When the leader continues, it reasserts its flight, and the calls that waited join it. When its process dies instead, the kernel frees the key lock, the joiners get `FlightInterruptedError`, and the next call leads.
177
+ - **A leader loses its lease.** This occurs only when a new coordinator refuses its reassert, because it knows a newer flight of the key, or when this process cannot connect to a coordinator again. The signal of the lease aborts with `LeaseLostError`, and the call of the leader rejects with that error. When the work throws its own error after the loss, the call rejects with a new `LeaseLostError`, and the error of the work is its `cause`. Thus `LeaseLostError` tells the leader that its outcome reached no joiner. Its joiners get `FlightInterruptedError`. The leader keeps the key lock until its work ends, so the next flight of the key runs after it, not beside it. [ADR 0007](./docs/adr/0007-a-work-error-after-a-lost-lease-rejects-with-leaselosterror.md) tells why.
178
+ - **A joiner's leader and the coordinator stop together.** The joiner gets `FlightInterruptedError` from the new coordinator. It never runs the work again.
176
179
 
177
180
  A call that was on its way to a coordinator that stopped joined nothing. It goes again to the next coordinator as a new call. [ADR 0005](./docs/adr/0005-a-joiner-rejoins-its-flight-by-its-token.md) tells why.
178
181
 
182
+ ### How long a call waits
183
+
184
+ - A call of a key waits with no limit while a process that lives holds the key lock, for example a frozen leader, or a leader whose work does not end. To set a limit, give a `signal`. A call of another key does not wait for it.
185
+ - Two flights of one key that follow each other wait about 10 ms between them. The leader frees the key lock only when it reads the acknowledgment of its landing, so the next call of the key waits for one more check of the key lock.
186
+
179
187
  ## Changes from 0.3.x
180
188
 
181
189
  Version 0.3.13 to 0.3.15 had a pull design. These parts changed:
@@ -197,9 +205,9 @@ Version 0.3.13 to 0.3.15 had a pull design. These parts changed:
197
205
  - [ADR 0006: The election and the connection are a copy of the mutex code](./docs/adr/0006-the-election-and-the-connection-are-a-copy-of-the-mutex-code.md)
198
206
  - [ADR 0007: A work error after a lost lease rejects with LeaseLostError](./docs/adr/0007-a-work-error-after-a-lost-lease-rejects-with-leaselosterror.md)
199
207
  - [ADR 0008: A connection closes only when its framing breaks](./docs/adr/0008-a-connection-closes-only-when-its-framing-breaks.md)
200
- - [ADR 0009: The next coordinator skips the grace window after a clean shutdown](./docs/adr/0009-the-next-coordinator-skips-the-grace-window-after-a-clean-shutdown.md)
208
+ - [ADR 0010: A leader holds a kernel lock on its key until its outcome is handed over](./docs/adr/0010-a-leader-holds-a-kernel-lock-on-its-key-until-its-outcome-is-handed-over.md)
201
209
  - [Code copied from the mutex](./docs/copied-from-mutex.md): each copied file, what changed, and why; the rules that the single flight shares with the mutex; and the code that is in two places inside the single flight.
202
- - Superseded: [ADR 0001](./docs/adr/0001-a-joiner-follows-its-flight-record-without-acquiring-the-key.md) and [ADR 0002](./docs/adr/0002-a-flight-that-all-callers-left-is-abandoned.md).
210
+ - Superseded: [ADR 0001](./docs/adr/0001-a-joiner-follows-its-flight-record-without-acquiring-the-key.md), [ADR 0002](./docs/adr/0002-a-flight-that-all-callers-left-is-abandoned.md) and [ADR 0009](./docs/adr/0009-the-next-coordinator-skips-the-grace-window-after-a-clean-shutdown.md).
203
211
 
204
212
  ## Development
205
213
 
@@ -220,7 +228,8 @@ src/
220
228
  codec.ts the Codec interface
221
229
  errors.ts FlightFailedError, FlightInterruptedError
222
230
  client/ the requests of one process: runs, leads, landings
223
- coordinator/ the coordinator of one term: flights, sessions, its server
231
+ coordinator/ the coordinator of one term: flights, sessions, parked runs, its server
232
+ key-lock/ the key locks: the kernel lock on each key that a leader holds
224
233
  protocol/ the messages between a process and its coordinator
225
234
  connection/ the socket, the handshake and the supervisor (a copy); the election of the directory (@zukhruf/election)
226
235
  shared/ the record check (a copy); file writes and the network directory check are in @zukhruf/fs
@@ -1,5 +1,6 @@
1
1
  import { FencingToken } from '@zukhruf/fencing';
2
2
  import type { ConnectionSupervisor } from '../connection/connection-supervisor.ts';
3
+ import type { KeyLocks } from '../key-lock/key-locks.ts';
3
4
  import { type FlightRequest, type Outcome } from '../protocol/flight-protocol.ts';
4
5
  /** This process leads a flight: it runs the work and lands the outcome. */
5
6
  export interface Lead {
@@ -8,6 +9,8 @@ export interface Lead {
8
9
  readonly signal: AbortSignal;
9
10
  /** Ends the flight with `outcome` for every joiner. Kept and sent again until a coordinator acknowledges it. */
10
11
  land(outcome: Outcome): void;
12
+ /** The work settled. The key's lock waits for this, so call it on every path, also when the work never landed. */
13
+ ended(): void;
11
14
  }
12
15
  /** How the coordinator answered a run for good. */
13
16
  export type Answer = {
@@ -19,6 +22,11 @@ export type Answer = {
19
22
  } | {
20
23
  kind: 'interrupted';
21
24
  };
25
+ export interface FlightClientOptions {
26
+ locks: KeyLocks;
27
+ /** Whether no coordinator of a newer term than the one that minted `token` has been elected. */
28
+ isCurrentTerm(token: FencingToken): Promise<boolean>;
29
+ }
22
30
  export interface RunRequest {
23
31
  signal?: AbortSignal | undefined;
24
32
  onJoin?: (() => void) | undefined;
@@ -32,7 +40,7 @@ export interface RunRequest {
32
40
  */
33
41
  export declare class FlightClient {
34
42
  #private;
35
- constructor(link: ConnectionSupervisor<FlightRequest>);
43
+ constructor(link: ConnectionSupervisor<FlightRequest>, { locks, isCurrentTerm }: FlightClientOptions);
36
44
  run(key: string, { signal, onJoin }: RunRequest): Promise<Answer>;
37
45
  /**
38
46
  * Disconnects for good, once every landing reached a coordinator: a landing
@@ -1 +1 @@
1
- {"version":3,"file":"flight-client.d.ts","sourceRoot":"","sources":["../../src/client/flight-client.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AACnF,OAAO,EACL,KAAK,aAAa,EAElB,KAAK,OAAO,EAEb,MAAM,gCAAgC,CAAC;AAExC,2EAA2E;AAC3E,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,iFAAiF;IACjF,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,gHAAgH;IAChH,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9B;AAED,mDAAmD;AACnD,MAAM,MAAM,MAAM,GACd;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAC5B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC;AAE5B,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACjC,MAAM,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;CACnC;AAuBD;;;;;;GAMG;AACH,qBAAa,YAAY;;gBAOX,IAAI,EAAE,oBAAoB,CAAC,aAAa,CAAC;IAW/C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IA2BvE;;;;OAIG;IACG,KAAK;CAqKZ"}
1
+ {"version":3,"file":"flight-client.d.ts","sourceRoot":"","sources":["../../src/client/flight-client.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAEnF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EACL,KAAK,aAAa,EAElB,KAAK,OAAO,EAEb,MAAM,gCAAgC,CAAC;AAExC,2EAA2E;AAC3E,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,iFAAiF;IACjF,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,gHAAgH;IAChH,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,kHAAkH;IAClH,KAAK,IAAI,IAAI,CAAC;CACf;AAED,mDAAmD;AACnD,MAAM,MAAM,MAAM,GACd;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAC5B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC;AAE5B,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,QAAQ,CAAC;IAChB,gGAAgG;IAChG,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACtD;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACjC,MAAM,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;CACnC;AAiCD;;;;;;GAMG;AACH,qBAAa,YAAY;;gBAUrB,IAAI,EAAE,oBAAoB,CAAC,aAAa,CAAC,EACzC,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,mBAAmB;IAczC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IA8BvE;;;;OAIG;IACG,KAAK;CA2OZ"}
@@ -2,6 +2,7 @@ import { randomUUID } from 'node:crypto';
2
2
  import { untilAborted } from '@zukhruf/async';
3
3
  import { FencingToken } from '@zukhruf/fencing';
4
4
  import { LeaseController } from '@zukhruf/lease';
5
+ import { KeyHold } from "../key-lock/key-hold.js";
5
6
  import { isFlightResponse, } from "../protocol/flight-protocol.js";
6
7
  /**
7
8
  * Sends runs to the coordinator over a supervised connection. When the
@@ -12,12 +13,16 @@ import { isFlightResponse, } from "../protocol/flight-protocol.js";
12
13
  */
13
14
  export class FlightClient {
14
15
  #link;
16
+ #locks;
17
+ #isCurrentTerm;
15
18
  #pending = new Map();
16
19
  #held = new Map();
17
20
  /** Wakes `close` each time a flight this process leads is acknowledged or lost. */
18
21
  #released = new Set();
19
- constructor(link) {
22
+ constructor(link, { locks, isCurrentTerm }) {
20
23
  this.#link = link;
24
+ this.#locks = locks;
25
+ this.#isCurrentTerm = isCurrentTerm;
21
26
  link.on('connected', () => this.#resume());
22
27
  // A message this client cannot read answers nothing it waits for.
23
28
  link.on('message', (message) => {
@@ -37,7 +42,7 @@ export class FlightClient {
37
42
  const pending = {
38
43
  key,
39
44
  onJoin,
40
- delivery: 'queued',
45
+ delivery: { kind: 'queued' },
41
46
  flight: undefined,
42
47
  resolve,
43
48
  reject,
@@ -50,8 +55,10 @@ export class FlightClient {
50
55
  return await untilAborted(promise, signal);
51
56
  }
52
57
  catch (error) {
53
- if (signal?.aborted)
58
+ if (signal?.aborted) {
54
59
  this.#withdraw(id);
60
+ this.#abandon(id);
61
+ }
55
62
  throw error;
56
63
  }
57
64
  }
@@ -68,6 +75,9 @@ export class FlightClient {
68
75
  for (const id of [...this.#pending.keys()]) {
69
76
  this.#take(id)?.reject(new Error('This single flight is closed.'));
70
77
  }
78
+ // The coordinator interrupts the flights of a closed connection, so they need nothing more from this process.
79
+ for (const id of [...this.#held.keys()])
80
+ this.#release(id);
71
81
  await closing;
72
82
  }
73
83
  #dispatch(id, pending) {
@@ -76,22 +86,72 @@ export class FlightClient {
76
86
  ? { op: 'run', id, key }
77
87
  : { op: 'run', id, key, flight };
78
88
  if (this.#link.send(request))
79
- pending.delivery = 'sent';
89
+ pending.delivery = { kind: 'sent' };
80
90
  }
81
91
  /**
82
92
  * The caller gave up. A run the coordinator may have heard is withdrawn;
83
93
  * one that already leads is not pending any more, so its flight runs on.
94
+ * A run that waits for its key's lock leads at the coordinator, so the
95
+ * cancel interrupts that flight: its work never started.
84
96
  */
85
97
  #withdraw(id) {
86
98
  const pending = this.#take(id);
87
- if (pending?.delivery === 'sent')
99
+ if (pending && pending.delivery.kind !== 'queued') {
88
100
  this.#link.send({ op: 'cancel', id });
101
+ }
89
102
  }
90
- #hold(id, key, token) {
103
+ /**
104
+ * The caller gave up although its run had led: the abort won the race with
105
+ * the answer, so nobody runs the work. The flight is interrupted, and the
106
+ * key's lock goes, instead of leading for the life of the process.
107
+ */
108
+ #abandon(id) {
109
+ const held = this.#held.get(id);
110
+ if (!held)
111
+ return;
112
+ this.#link.send({ op: 'cancel', id });
113
+ this.#release(id);
114
+ held.hold.workEnded();
115
+ }
116
+ /**
117
+ * Told to lead: the run leads only once it holds its key's lock, so no
118
+ * other process runs the key's work beside it. A grant of an older term is
119
+ * stale: the coordinator that minted it is gone, and its successor may have
120
+ * let another run lead. That run goes again as a plain run.
121
+ */
122
+ async #lock(id, pending, token, stop) {
123
+ try {
124
+ using locked = new DisposableStack();
125
+ locked.use(await this.#locks.acquire(pending.key, stop));
126
+ const current = await this.#isCurrentTerm(token);
127
+ if (stop.aborted)
128
+ return;
129
+ if (!current) {
130
+ locked.dispose();
131
+ pending.delivery = { kind: 'queued' };
132
+ this.#dispatch(id, pending);
133
+ return;
134
+ }
135
+ this.#take(id);
136
+ pending.resolve({
137
+ kind: 'lead',
138
+ lead: this.#hold(id, pending.key, token, new KeyHold(locked.move())),
139
+ });
140
+ }
141
+ catch (error) {
142
+ // An abort is the run's own end: it was answered, withdrawn or sent again.
143
+ if (stop.aborted)
144
+ return;
145
+ this.#take(id)?.reject(error);
146
+ this.#link.send({ op: 'cancel', id });
147
+ }
148
+ }
149
+ #hold(id, key, token, hold) {
91
150
  const held = {
92
151
  key,
93
152
  token,
94
153
  lease: new LeaseController(key),
154
+ hold,
95
155
  landing: undefined,
96
156
  };
97
157
  this.#held.set(id, held);
@@ -106,6 +166,7 @@ export class FlightClient {
106
166
  this.#updateRef();
107
167
  this.#link.send({ op: 'land', id, outcome });
108
168
  },
169
+ ended: () => hold.workEnded(),
109
170
  };
110
171
  }
111
172
  /** The flight of `id` is no longer this leader's, so its lease is told and nothing reasserts it. */
@@ -118,6 +179,7 @@ export class FlightClient {
118
179
  }
119
180
  /** The flight of `id` needs nothing more from this process. */
120
181
  #release(id) {
182
+ this.#held.get(id)?.hold.flightEnded();
121
183
  this.#held.delete(id);
122
184
  this.#updateRef();
123
185
  const waiting = [...this.#released];
@@ -129,14 +191,13 @@ export class FlightClient {
129
191
  switch (response.op) {
130
192
  case 'lead': {
131
193
  // A run withdrawn meanwhile sent `cancel`, which interrupts the flight at the coordinator.
132
- const pending = this.#take(response.id);
194
+ const pending = this.#pending.get(response.id);
133
195
  if (!pending)
134
196
  return;
135
- const token = FencingToken.parse(response.token);
136
- pending.resolve({
137
- kind: 'lead',
138
- lead: this.#hold(response.id, pending.key, token),
139
- });
197
+ const stop = new AbortController();
198
+ pending.delivery = { kind: 'locking', stop };
199
+ // The first try of the lock is synchronous, here: only microtasks separate it from the work.
200
+ void this.#lock(response.id, pending, FencingToken.parse(response.token), stop.signal);
140
201
  return;
141
202
  }
142
203
  case 'joined': {
@@ -195,14 +256,21 @@ export class FlightClient {
195
256
  this.#link.send({ op: 'land', id, outcome: landing });
196
257
  }
197
258
  for (const [id, pending] of this.#pending) {
198
- if (pending.delivery === 'queued')
259
+ if (pending.delivery.kind === 'queued')
199
260
  this.#dispatch(id, pending);
200
261
  }
201
262
  }
202
- /** Nothing sent on the lost connection will be answered, so every run goes again on the next one. */
263
+ /**
264
+ * Nothing sent on the lost connection will be answered, so every run goes
265
+ * again on the next one. A run that waits for its key's lock had not led
266
+ * yet: the next coordinator may not know its flight, so it goes again too.
267
+ */
203
268
  #interrupt() {
204
- for (const pending of this.#pending.values())
205
- pending.delivery = 'queued';
269
+ for (const pending of this.#pending.values()) {
270
+ if (pending.delivery.kind === 'locking')
271
+ pending.delivery.stop.abort();
272
+ pending.delivery = { kind: 'queued' };
273
+ }
206
274
  }
207
275
  /** No coordinator heard the reassertions, so the flights this process leads may be interrupted already. */
208
276
  #fail(error) {
@@ -216,6 +284,8 @@ export class FlightClient {
216
284
  const pending = this.#pending.get(id);
217
285
  if (!pending)
218
286
  return undefined;
287
+ if (pending.delivery.kind === 'locking')
288
+ pending.delivery.stop.abort();
219
289
  this.#pending.delete(id);
220
290
  this.#updateRef();
221
291
  return pending;
@@ -1 +1 @@
1
- {"version":3,"file":"flight-client.js","sourceRoot":"","sources":["../../src/client/flight-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"flight-client.js","sourceRoot":"","sources":["../../src/client/flight-client.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import type { FencingToken, TokenSource } from '@zukhruf/fencing';
2
2
  import type { Connection } from '../connection/connection.ts';
3
+ import type { KeyLocks } from '../key-lock/key-locks.ts';
3
4
  import type { FlightResponse, Outcome } from '../protocol/flight-protocol.ts';
4
5
  import { Flight } from './flight.ts';
5
6
  import type { Party } from './party.ts';
@@ -7,29 +8,40 @@ export interface FlightCoordinatorOptions {
7
8
  /** Mints the lease token of each flight this coordinator starts. */
8
9
  tokens: TokenSource;
9
10
  /**
10
- * Milliseconds after start during which no flight starts, so leaders from a
11
- * previous coordinator can reassert their flights first. Zero when no
12
- * earlier coordinator can have left a flight in progress.
11
+ * The kernel locks on the keys. A process that holds a key's lock runs its
12
+ * work, whether this coordinator knows that flight or not.
13
13
  */
14
- graceWindow: number;
14
+ locks: KeyLocks;
15
15
  }
16
16
  /**
17
17
  * Coordinates the flights of one term. A run leads a new flight of its key, or
18
18
  * joins the flight of that key in progress, in one step, so two runs never
19
19
  * both lead. The outcome is pushed to every joiner as soon as it lands.
20
+ *
21
+ * A key whose lock another process holds, while no flight of it is known
22
+ * here, runs the work of a leader that has not reasserted its flight yet, so
23
+ * its runs and rejoins wait for that flight or for the lock to free. A leader
24
+ * keeps its flight while its process lives.
20
25
  */
21
26
  export declare class FlightCoordinator {
22
27
  #private;
23
- constructor({ tokens, graceWindow }: FlightCoordinatorOptions);
24
- /**
25
- * Whether the next coordinator would find nothing to recover: no flight is
26
- * in progress, and the grace window is over or there was none.
27
- */
28
- get leavesNothingToRecover(): boolean;
28
+ constructor({ tokens, locks }: FlightCoordinatorOptions);
29
29
  serve(connection: Connection<FlightResponse>): void;
30
+ /** Stops watching the locks of the keys whose runs wait. */
31
+ close(): void;
32
+ /** Rejects only when no token can be minted. */
30
33
  run(party: Party, key: string): Promise<void>;
31
- /** A joiner that lost its connection, back for the flight it joined: it never leads, so its work never runs twice. */
32
- rejoin(party: Party, key: string, flight: string): Promise<void>;
34
+ /**
35
+ * A joiner that lost its connection, back for the flight it joined: it never
36
+ * leads, so its work never runs twice. A rejoin joins only its own flight;
37
+ * any other answer could be a second run of the work.
38
+ */
39
+ rejoin(party: Party, key: string, flight: string): void;
40
+ /**
41
+ * A leader claims its flight again after its connection was lost. The same
42
+ * flight, through a new connection, stays one flight with its joiners. For
43
+ * two flights of one key, the newer token wins, and the older flight is lost.
44
+ */
33
45
  reassert(party: Party, key: string, token: FencingToken): void;
34
46
  land(flight: Flight, outcome: Outcome): void;
35
47
  /** The leader withdrew or its connection is gone. */
@@ -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,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;AAWD;;;;GAIG;AACH,qBAAa,iBAAiB;;gBAGhB,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,wBAAwB;IAgB7D;;;OAGG;IACH,IAAI,sBAAsB,IAAI,OAAO,CAEpC;IAED,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"}
1
+ {"version":3,"file":"flight-coordinator.d.ts","sourceRoot":"","sources":["../../src/coordinator/flight-coordinator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAElE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGxC,MAAM,WAAW,wBAAwB;IACvC,oEAAoE;IACpE,MAAM,EAAE,WAAW,CAAC;IACpB;;;OAGG;IACH,KAAK,EAAE,QAAQ,CAAC;CACjB;AAQD;;;;;;;;;GASG;AACH,qBAAa,iBAAiB;;gBAShB,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,wBAAwB;IAMvD,KAAK,CAAC,UAAU,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,IAAI;IAInD,4DAA4D;IAC5D,KAAK,IAAI,IAAI;IAIb,gDAAgD;IAC1C,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM;IAKnC;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAevD;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI;IAe9D,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;IAKrC,qDAAqD;IACrD,SAAS,CAAC,MAAM,EAAE,MAAM;CAwDzB"}