@zukhruf/mutex 0.1.0 → 0.3.0

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 (130) hide show
  1. package/README.md +4 -2
  2. package/dist/fencing/file-token-source.js +2 -2
  3. package/dist/fencing/file-token-source.js.map +1 -1
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +1 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/leader-election/index.d.ts +1 -0
  9. package/dist/leader-election/index.d.ts.map +1 -1
  10. package/dist/leader-election/index.js +1 -0
  11. package/dist/leader-election/index.js.map +1 -1
  12. package/dist/leader-election/leader-election.d.ts.map +1 -1
  13. package/dist/leader-election/leader-election.js +4 -2
  14. package/dist/leader-election/leader-election.js.map +1 -1
  15. package/dist/local-directory/local-directory.d.ts +7 -0
  16. package/dist/local-directory/local-directory.d.ts.map +1 -0
  17. package/dist/local-directory/local-directory.js +75 -0
  18. package/dist/local-directory/local-directory.js.map +1 -0
  19. package/dist/local-directory/network-directory-error.d.ts +8 -0
  20. package/dist/local-directory/network-directory-error.d.ts.map +1 -0
  21. package/dist/local-directory/network-directory-error.js +13 -0
  22. package/dist/local-directory/network-directory-error.js.map +1 -0
  23. package/dist/lock-stores/file-system/file-lock-store.d.ts.map +1 -1
  24. package/dist/lock-stores/file-system/file-lock-store.js +4 -1
  25. package/dist/lock-stores/file-system/file-lock-store.js.map +1 -1
  26. package/dist/lock-stores/file-system/lock-file-store.d.ts.map +1 -1
  27. package/dist/lock-stores/file-system/lock-file-store.js +9 -4
  28. package/dist/lock-stores/file-system/lock-file-store.js.map +1 -1
  29. package/dist/lock-stores/file-system/ticket-queue-file-store.d.ts.map +1 -1
  30. package/dist/lock-stores/file-system/ticket-queue-file-store.js +3 -2
  31. package/dist/lock-stores/file-system/ticket-queue-file-store.js.map +1 -1
  32. package/dist/lock-stores/ipc/child-process-connection.d.ts +3 -3
  33. package/dist/lock-stores/ipc/child-process-connection.d.ts.map +1 -1
  34. package/dist/lock-stores/ipc/child-process-connection.js +16 -20
  35. package/dist/lock-stores/ipc/child-process-connection.js.map +1 -1
  36. package/dist/lock-stores/ipc/ipc-store.d.ts.map +1 -1
  37. package/dist/lock-stores/ipc/ipc-store.js +7 -5
  38. package/dist/lock-stores/ipc/ipc-store.js.map +1 -1
  39. package/dist/lock-stores/ipc/process-channel-connection.d.ts +4 -3
  40. package/dist/lock-stores/ipc/process-channel-connection.d.ts.map +1 -1
  41. package/dist/lock-stores/ipc/process-channel-connection.js +6 -14
  42. package/dist/lock-stores/ipc/process-channel-connection.js.map +1 -1
  43. package/dist/lock-stores/memory/memory-store.d.ts +1 -1
  44. package/dist/lock-stores/memory/memory-store.d.ts.map +1 -1
  45. package/dist/lock-stores/memory/memory-store.js +13 -14
  46. package/dist/lock-stores/memory/memory-store.js.map +1 -1
  47. package/dist/lock-stores/remote/connection-supervisor.d.ts +39 -0
  48. package/dist/lock-stores/remote/connection-supervisor.d.ts.map +1 -0
  49. package/dist/lock-stores/remote/connection-supervisor.js +195 -0
  50. package/dist/lock-stores/remote/connection-supervisor.js.map +1 -0
  51. package/dist/lock-stores/remote/connection.d.ts +11 -7
  52. package/dist/lock-stores/remote/connection.d.ts.map +1 -1
  53. package/dist/lock-stores/remote/connector.d.ts +5 -2
  54. package/dist/lock-stores/remote/connector.d.ts.map +1 -1
  55. package/dist/lock-stores/remote/lock-coordinator.d.ts +2 -2
  56. package/dist/lock-stores/remote/lock-coordinator.d.ts.map +1 -1
  57. package/dist/lock-stores/remote/lock-coordinator.js +140 -69
  58. package/dist/lock-stores/remote/lock-coordinator.js.map +1 -1
  59. package/dist/lock-stores/remote/remote-lock-client.d.ts +8 -7
  60. package/dist/lock-stores/remote/remote-lock-client.d.ts.map +1 -1
  61. package/dist/lock-stores/remote/remote-lock-client.js +99 -99
  62. package/dist/lock-stores/remote/remote-lock-client.js.map +1 -1
  63. package/dist/lock-stores/socket/electing-connector.d.ts +7 -4
  64. package/dist/lock-stores/socket/electing-connector.d.ts.map +1 -1
  65. package/dist/lock-stores/socket/electing-connector.js +35 -8
  66. package/dist/lock-stores/socket/electing-connector.js.map +1 -1
  67. package/dist/lock-stores/socket/local-directory-connector.d.ts +14 -0
  68. package/dist/lock-stores/socket/local-directory-connector.d.ts.map +1 -0
  69. package/dist/lock-stores/socket/local-directory-connector.js +23 -0
  70. package/dist/lock-stores/socket/local-directory-connector.js.map +1 -0
  71. package/dist/lock-stores/socket/socket-connection.d.ts +3 -3
  72. package/dist/lock-stores/socket/socket-connection.d.ts.map +1 -1
  73. package/dist/lock-stores/socket/socket-connection.js +16 -18
  74. package/dist/lock-stores/socket/socket-connection.js.map +1 -1
  75. package/dist/lock-stores/socket/socket-store.d.ts +1 -2
  76. package/dist/lock-stores/socket/socket-store.d.ts.map +1 -1
  77. package/dist/lock-stores/socket/socket-store.js +16 -23
  78. package/dist/lock-stores/socket/socket-store.js.map +1 -1
  79. package/dist/lock-stores/thread/parent-port-connection.d.ts +4 -3
  80. package/dist/lock-stores/thread/parent-port-connection.d.ts.map +1 -1
  81. package/dist/lock-stores/thread/parent-port-connection.js +6 -13
  82. package/dist/lock-stores/thread/parent-port-connection.js.map +1 -1
  83. package/dist/lock-stores/thread/thread-store.d.ts.map +1 -1
  84. package/dist/lock-stores/thread/thread-store.js +5 -8
  85. package/dist/lock-stores/thread/thread-store.js.map +1 -1
  86. package/dist/lock-stores/thread/worker-connection.d.ts +3 -3
  87. package/dist/lock-stores/thread/worker-connection.d.ts.map +1 -1
  88. package/dist/lock-stores/thread/worker-connection.js +19 -23
  89. package/dist/lock-stores/thread/worker-connection.js.map +1 -1
  90. package/dist/mutex/acquire-mode.d.ts +6 -3
  91. package/dist/mutex/acquire-mode.d.ts.map +1 -1
  92. package/dist/mutex/acquire-modes/skip-if-busy-mode.d.ts +7 -3
  93. package/dist/mutex/acquire-modes/skip-if-busy-mode.d.ts.map +1 -1
  94. package/dist/mutex/acquire-modes/skip-if-busy-mode.js +7 -4
  95. package/dist/mutex/acquire-modes/skip-if-busy-mode.js.map +1 -1
  96. package/dist/mutex/acquire-modes/wait-mode.d.ts +2 -2
  97. package/dist/mutex/acquire-modes/wait-mode.d.ts.map +1 -1
  98. package/dist/mutex/acquire-modes/wait-mode.js +2 -2
  99. package/dist/mutex/acquire-modes/wait-mode.js.map +1 -1
  100. package/dist/mutex/key.d.ts +3 -2
  101. package/dist/mutex/key.d.ts.map +1 -1
  102. package/dist/mutex/key.js +3 -3
  103. package/dist/mutex/key.js.map +1 -1
  104. package/dist/mutex/mutex.d.ts +3 -3
  105. package/dist/mutex/mutex.d.ts.map +1 -1
  106. package/dist/mutex/mutex.js +28 -5
  107. package/dist/mutex/mutex.js.map +1 -1
  108. package/dist/shared/fs/atomic-write.d.ts.map +1 -1
  109. package/dist/shared/fs/atomic-write.js +3 -27
  110. package/dist/shared/fs/atomic-write.js.map +1 -1
  111. package/dist/shared/fs/create-exclusive.d.ts.map +1 -1
  112. package/dist/shared/fs/create-exclusive.js +7 -2
  113. package/dist/shared/fs/create-exclusive.js.map +1 -1
  114. package/dist/shared/fs/durable-write.d.ts +7 -0
  115. package/dist/shared/fs/durable-write.d.ts.map +1 -0
  116. package/dist/shared/fs/durable-write.js +46 -0
  117. package/dist/shared/fs/durable-write.js.map +1 -0
  118. package/dist/shared/fs/patiently.d.ts +3 -0
  119. package/dist/shared/fs/patiently.d.ts.map +1 -0
  120. package/dist/shared/fs/patiently.js +30 -0
  121. package/dist/shared/fs/patiently.js.map +1 -0
  122. package/dist/shared/fs/replace-file.d.ts +8 -0
  123. package/dist/shared/fs/replace-file.d.ts.map +1 -0
  124. package/dist/shared/fs/replace-file.js +12 -0
  125. package/dist/shared/fs/replace-file.js.map +1 -0
  126. package/dist/shared/latch.d.ts +10 -0
  127. package/dist/shared/latch.d.ts.map +1 -0
  128. package/dist/shared/latch.js +14 -0
  129. package/dist/shared/latch.js.map +1 -0
  130. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
- import { setTimeout as delay } from 'node:timers/promises';
2
1
  import { FencingToken } from "../../fencing/fencing-token.js";
2
+ import { Latch } from "../../shared/latch.js";
3
3
  import { untilAborted } from "../../shared/until-aborted.js";
4
4
  import { MemoryStore } from "../memory/memory-store.js";
5
5
  /**
@@ -7,29 +7,29 @@ import { MemoryStore } from "../memory/memory-store.js";
7
7
  * connections. A peer that disconnects releases everything it held or waited for.
8
8
  */
9
9
  export class LockCoordinator {
10
- #store;
11
- #graceOver;
12
- #reassertions = new Map();
13
- #inGrace;
10
+ #phase;
14
11
  constructor({ tokens, graceWindow = 0 }) {
15
- this.#store = new MemoryStore({ tokens });
16
- this.#inGrace = graceWindow > 0;
17
- this.#graceOver = this.#inGrace
18
- ? delay(graceWindow, undefined, { ref: false }).then(() => {
19
- this.#inGrace = false;
20
- this.#reassertions.clear();
21
- })
22
- : Promise.resolve();
23
- }
24
- async acquire(key, { signal } = {}) {
25
- await untilAborted(this.#graceOver, signal);
26
- return this.#store.acquire(key, { signal });
12
+ const store = new MemoryStore({ tokens });
13
+ const granting = new Granting(store);
14
+ if (graceWindow > 0) {
15
+ const over = new Latch();
16
+ this.#phase = new GraceWindow(store, over, granting);
17
+ setTimeout(() => {
18
+ // Granting is current before the latch lets the waiters resume.
19
+ this.#phase = granting;
20
+ over.open();
21
+ }, graceWindow).unref();
22
+ }
23
+ else {
24
+ this.#phase = granting;
25
+ }
26
+ }
27
+ async acquire(key, options = {}) {
28
+ return this.#phase.acquire(key, options);
27
29
  }
28
30
  /** Nothing is granted during the grace window, so a key counts as busy then. */
29
31
  async tryAcquire(key) {
30
- if (this.#inGrace)
31
- return undefined;
32
- return this.#store.tryAcquire(key);
32
+ return this.#phase.tryAcquire(key);
33
33
  }
34
34
  serve(connection) {
35
35
  new Session(this, connection);
@@ -37,39 +37,70 @@ export class LockCoordinator {
37
37
  /**
38
38
  * Re-registers a holder from before a failover. Accepted only during the
39
39
  * grace window; for two claims on one key the newer token wins and the older
40
- * claim's `lose` is called. Resolves `undefined` when the claim is refused.
40
+ * claim's `lose` is called. Returns `undefined` when the claim is refused.
41
41
  */
42
42
  reassert(key, token, lose) {
43
- if (!this.#inGrace)
44
- return undefined;
43
+ return this.#phase.reassert(key, token, lose);
44
+ }
45
+ }
46
+ /** The only phase that grants. A holder that reasserts now is too late. */
47
+ class Granting {
48
+ #store;
49
+ constructor(store) {
50
+ this.#store = store;
51
+ }
52
+ acquire(key, { signal }) {
53
+ return this.#store.acquire(key, { signal });
54
+ }
55
+ tryAcquire(key) {
56
+ return this.#store.tryAcquire(key);
57
+ }
58
+ reassert() {
59
+ return undefined;
60
+ }
61
+ }
62
+ /** Grants nothing, so holders from a previous coordinator can reassert their keys first. */
63
+ class GraceWindow {
64
+ #store;
65
+ #over;
66
+ #next;
67
+ #reassertions = new Map();
68
+ constructor(store, over, next) {
69
+ this.#store = store;
70
+ this.#over = over;
71
+ this.#next = next;
72
+ }
73
+ async acquire(key, { signal }) {
74
+ await untilAborted(this.#over.wait(), signal);
75
+ return this.#next.acquire(key, { signal });
76
+ }
77
+ async tryAcquire() {
78
+ return undefined;
79
+ }
80
+ reassert(key, token, lose) {
45
81
  const existing = this.#reassertions.get(key);
46
82
  if (existing && !token.isNewerThan(existing.token))
47
83
  return undefined;
84
+ // Waiters join the line only after grace, so this claim is next once the
85
+ // claim it outranks gives the key back, even if that claim already let it go.
86
+ const lease = this.#store.acquire(key);
48
87
  existing?.lose();
49
- // Nothing is granted during grace, so the first claim gets the key at once
50
- // and a newer claim takes over that same lease.
51
- const lease = existing?.lease ?? this.#store.acquire(key);
52
- this.#reassertions.set(key, { token, lease, lose });
88
+ this.#reassertions.set(key, { token, lose });
53
89
  return lease;
54
90
  }
55
91
  }
56
92
  class Session {
57
93
  #coordinator;
58
- #connection;
59
- #leases = new Map();
60
94
  #requested = new Set();
61
- #lost = new Set();
62
- #closed = false;
95
+ #phase;
63
96
  constructor(coordinator, connection) {
64
97
  this.#coordinator = coordinator;
65
- this.#connection = connection;
66
- connection.listen({
67
- message: (request) => {
68
- this.#handle(request).catch(() => connection.close());
69
- },
70
- close: () => {
71
- void this.#close();
72
- },
98
+ this.#phase = new Serving(connection);
99
+ connection.on('message', (request) => {
100
+ this.#handle(request).catch(() => connection.close());
101
+ });
102
+ connection.once('close', () => {
103
+ void this.#end();
73
104
  });
74
105
  }
75
106
  async #handle(request) {
@@ -80,7 +111,7 @@ class Session {
80
111
  return;
81
112
  this.#requested.add(request.id);
82
113
  const lease = await this.#coordinator.acquire(request.key);
83
- return this.#grant(request.id, lease);
114
+ return this.#grant(lease, request.id);
84
115
  }
85
116
  case 'try': {
86
117
  if (this.#requested.has(request.id))
@@ -89,62 +120,102 @@ class Session {
89
120
  const lease = await this.#coordinator.tryAcquire(request.key);
90
121
  if (!lease) {
91
122
  this.#requested.delete(request.id);
92
- return this.#reply({ op: 'busy', id: request.id });
123
+ return this.#phase.reply({ op: 'busy', id: request.id });
93
124
  }
94
- return this.#grant(request.id, lease);
125
+ return this.#grant(lease, request.id);
95
126
  }
96
127
  case 'cancel': {
97
128
  // A request still in line is released by #grant when its turn comes.
98
129
  this.#requested.delete(request.id);
99
- return this.#releaseLease(request.id);
130
+ return this.#phase.release(request.id);
100
131
  }
101
132
  case 'release': {
102
133
  this.#requested.delete(request.id);
103
- return this.#releaseLease(request.id);
134
+ return this.#phase.release(request.id);
104
135
  }
105
136
  case 'reassert': {
137
+ // Registered like any request, so a release that arrives before the claim resolves gives the key back.
138
+ if (this.#requested.has(request.id))
139
+ return;
140
+ this.#requested.add(request.id);
106
141
  const claim = this.#coordinator.reassert(request.key, new FencingToken(BigInt(request.token)), () => this.#lose(request.id));
107
- if (!claim)
108
- return this.#reply({ op: 'rejected', id: request.id });
142
+ if (!claim) {
143
+ this.#requested.delete(request.id);
144
+ return this.#phase.reply({ op: 'rejected', id: request.id });
145
+ }
109
146
  const lease = await claim;
110
- if (this.#lost.has(request.id))
111
- return;
112
- if (this.#closed)
147
+ if (!this.#requested.has(request.id)) {
113
148
  return lease[Symbol.asyncDispose]();
114
- this.#leases.set(request.id, lease);
115
- return;
149
+ }
150
+ return this.#phase.keep(lease, request.id);
116
151
  }
117
152
  }
118
153
  }
119
- /** A request cancelled or a peer gone while the grant was on its way releases the key at once. */
120
- #grant(id, lease) {
121
- if (this.#closed || !this.#requested.has(id)) {
154
+ /** A request cancelled while the grant was on its way releases the key at once. */
155
+ #grant(lease, id) {
156
+ if (!this.#requested.has(id))
122
157
  return lease[Symbol.asyncDispose]();
123
- }
124
- this.#leases.set(id, lease);
125
- return this.#reply({ op: 'granted', id, token: lease.token.toString() });
158
+ return this.#phase.grant(lease, id);
126
159
  }
127
- #releaseLease(id) {
128
- const lease = this.#leases.get(id);
129
- this.#leases.delete(id);
130
- return lease?.[Symbol.asyncDispose]();
131
- }
132
- /** A newer claim took this session's reasserted lease over, so it must not release it. */
160
+ /** A newer claim outranked this session's reassertion, so the key goes to that claim next. */
133
161
  #lose(id) {
134
- this.#lost.add(id);
135
- this.#leases.delete(id);
136
- void this.#reply({ op: 'rejected', id });
162
+ // A holder that already released has nothing to give back and nothing to learn.
163
+ if (!this.#requested.delete(id))
164
+ return;
165
+ this.#phase.lose(id);
137
166
  }
138
- async #reply(response) {
167
+ /** Ends Serving before its leases are released, so a grant that arrives meanwhile is given back too. */
168
+ async #end() {
169
+ const serving = this.#phase;
170
+ this.#phase = new Ended();
171
+ await serving.end();
172
+ }
173
+ }
174
+ /** The peer is connected: the session keeps its leases and answers it. */
175
+ class Serving {
176
+ #connection;
177
+ #leases = new Map();
178
+ constructor(connection) {
179
+ this.#connection = connection;
180
+ }
181
+ async reply(response) {
139
182
  // A failed send means the peer is gone; `close` then releases its leases.
140
183
  await this.#connection.send(response).catch(() => { });
141
184
  }
142
- async #close() {
143
- this.#closed = true;
185
+ async grant(lease, id) {
186
+ this.#leases.set(id, lease);
187
+ await this.reply({ op: 'granted', id, token: lease.token.toString() });
188
+ }
189
+ async keep(lease, id) {
190
+ this.#leases.set(id, lease);
191
+ }
192
+ async release(id) {
193
+ const lease = this.#leases.get(id);
194
+ this.#leases.delete(id);
195
+ await lease?.[Symbol.asyncDispose]();
196
+ }
197
+ lose(id) {
198
+ void this.release(id);
199
+ void this.reply({ op: 'rejected', id });
200
+ }
201
+ async end() {
144
202
  const leases = [...this.#leases.values()];
145
203
  this.#leases.clear();
146
204
  for (const lease of leases)
147
205
  await lease[Symbol.asyncDispose]();
148
206
  }
149
207
  }
208
+ /** The peer is gone: a lease that still arrives is given back at once, and nothing is answered. */
209
+ class Ended {
210
+ async reply() { }
211
+ async grant(lease) {
212
+ await lease[Symbol.asyncDispose]();
213
+ }
214
+ async keep(lease) {
215
+ await lease[Symbol.asyncDispose]();
216
+ }
217
+ async release() { }
218
+ lose() { }
219
+ async end() { }
220
+ }
150
221
  //# sourceMappingURL=lock-coordinator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lock-coordinator.js","sourceRoot":"","sources":["../../../src/lock-stores/remote/lock-coordinator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lock-coordinator.js","sourceRoot":"","sources":["../../../src/lock-stores/remote/lock-coordinator.ts"],"names":[],"mappings":"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"}
@@ -1,17 +1,18 @@
1
1
  import type { Lease } from '../../mutex/lease.ts';
2
2
  import type { AcquireOptions, LockStore } from '../../mutex/lock-store.ts';
3
- import type { Connector } from './connector.ts';
3
+ import type { ConnectionSupervisor } from './connection-supervisor.ts';
4
+ import type { LockRequest, LockResponse } from './protocol.ts';
4
5
  /**
5
- * Asks a coordinator for keys over a connection. When the connection drops, it
6
- * asks its connector for another, reasserts the keys it holds and re-requests
7
- * the ones it waits for. A held key whose reassertion is refused is lost.
6
+ * Asks a coordinator for keys over a supervised connection. When the
7
+ * connection is replaced, it reasserts the keys it holds and asks again for the
8
+ * ones it waits for. A held key whose reassertion is refused is lost.
8
9
  */
9
10
  export declare class RemoteLockClient implements LockStore {
10
11
  #private;
11
- constructor(connector: Connector);
12
+ constructor(link: ConnectionSupervisor<LockRequest, LockResponse>);
12
13
  acquire(key: string, { signal }?: AcquireOptions): Promise<Lease>;
13
14
  tryAcquire(key: string): Promise<Lease | undefined>;
14
- /** Disconnects for good; the coordinator releases whatever this client still holds. */
15
- close(): void;
15
+ /** Disconnects for good. Over a socket, the coordinator then releases whatever this client still holds. */
16
+ close(): Promise<void>;
16
17
  }
17
18
  //# sourceMappingURL=remote-lock-client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"remote-lock-client.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/remote/remote-lock-client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAE3E,OAAO,KAAK,EAAoB,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAgBlE;;;;GAIG;AACH,qBAAa,gBAAiB,YAAW,SAAS;;gBASpC,SAAS,EAAE,SAAS;IAI1B,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,GAAE,cAAmB,GAAG,OAAO,CAAC,KAAK,CAAC;IA0BrE,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC;IAqFzD,uFAAuF;IACvF,KAAK;CA0CN"}
1
+ {"version":3,"file":"remote-lock-client.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/remote/remote-lock-client.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAE3E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAEvE,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAmB/D;;;;GAIG;AACH,qBAAa,gBAAiB,YAAW,SAAS;;gBAMpC,IAAI,EAAE,oBAAoB,CAAC,WAAW,EAAE,YAAY,CAAC;IAY3D,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,GAAE,cAAmB,GAAG,OAAO,CAAC,KAAK,CAAC;IAmBrE,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC;IAMzD,2GAA2G;IACrG,KAAK;CA0HZ"}
@@ -4,26 +4,30 @@ import { LockLostError } from "../../mutex/lock-lost-error.js";
4
4
  import { untilAborted } from "../../shared/until-aborted.js";
5
5
  import { CoordinatorUnavailableError } from "./coordinator-unavailable-error.js";
6
6
  /**
7
- * Asks a coordinator for keys over a connection. When the connection drops, it
8
- * asks its connector for another, reasserts the keys it holds and re-requests
9
- * the ones it waits for. A held key whose reassertion is refused is lost.
7
+ * Asks a coordinator for keys over a supervised connection. When the
8
+ * connection is replaced, it reasserts the keys it holds and asks again for the
9
+ * ones it waits for. A held key whose reassertion is refused is lost.
10
10
  */
11
11
  export class RemoteLockClient {
12
- #connector;
12
+ #link;
13
13
  #pending = new Map();
14
14
  #held = new Map();
15
15
  #lost = new Set();
16
- #connection;
17
- #current;
18
- #closed = false;
19
- constructor(connector) {
20
- this.#connector = connector;
16
+ constructor(link) {
17
+ this.#link = link;
18
+ link.on('connected', () => this.#resume());
19
+ link.on('message', (response) => this.#receive(response));
20
+ link.on('disconnected', () => this.#interrupt());
21
+ // Held keys stay exclusive: no coordinator is left to grant them to anyone else.
22
+ link.on('unavailable', () => this.#rejectAll((key) => new CoordinatorUnavailableError(key)));
23
+ link.on('failed', (error) => this.#fail(error));
21
24
  }
22
25
  async acquire(key, { signal } = {}) {
23
26
  signal?.throwIfAborted();
24
27
  const id = randomUUID();
28
+ const { answer } = this.#request(id, key, 'acquire');
25
29
  try {
26
- const token = await untilAborted(this.#request(id, key, 'acquire'), signal);
30
+ const token = await untilAborted(answer.promise, signal);
27
31
  // The coordinator answers 'busy' only to a try; an acquire waits for its grant.
28
32
  if (!token) {
29
33
  throw new Error(`The lock coordinator answered 'busy' to an acquire of key "${key}".`);
@@ -31,39 +35,52 @@ export class RemoteLockClient {
31
35
  return this.#hold(id, key, token);
32
36
  }
33
37
  catch (error) {
34
- if (signal?.aborted && this.#current) {
35
- void this.#send(this.#current, { op: 'cancel', id });
36
- }
38
+ if (signal?.aborted)
39
+ this.#withdraw(id);
37
40
  throw error;
38
41
  }
39
- finally {
40
- this.#pending.delete(id);
41
- this.#updateRef();
42
- }
43
42
  }
44
43
  async tryAcquire(key) {
45
44
  const id = randomUUID();
46
- try {
47
- const token = await this.#request(id, key, 'try');
48
- return token && this.#hold(id, key, token);
49
- }
50
- finally {
51
- this.#pending.delete(id);
52
- this.#updateRef();
53
- }
45
+ const token = await this.#request(id, key, 'try').answer.promise;
46
+ return token && this.#hold(id, key, token);
54
47
  }
55
- async #request(id, key, attempt) {
56
- if (this.#closed)
48
+ /** Disconnects for good. Over a socket, the coordinator then releases whatever this client still holds. */
49
+ async close() {
50
+ const closing = this.#link.close();
51
+ this.#rejectAll(() => new Error('This lock client is closed.'));
52
+ await closing;
53
+ }
54
+ #request(id, key, attempt) {
55
+ if (this.#link.status === 'closed') {
57
56
  throw new Error('This lock client is closed.');
58
- const answer = Promise.withResolvers();
59
- this.#pending.set(id, { key, attempt, answer });
60
- this.#updateRef();
61
- this.#connection ??= this.#open();
62
- const connection = await this.#connection;
63
- if (!connection)
57
+ }
58
+ if (this.#link.status === 'unavailable') {
64
59
  throw new CoordinatorUnavailableError(key);
65
- void this.#send(connection, { op: attempt, id, key });
66
- return answer.promise;
60
+ }
61
+ const pending = {
62
+ key,
63
+ attempt,
64
+ delivery: 'queued',
65
+ answer: Promise.withResolvers(),
66
+ };
67
+ this.#pending.set(id, pending);
68
+ this.#updateRef();
69
+ this.#link.open();
70
+ this.#dispatch(id, pending);
71
+ return pending;
72
+ }
73
+ #dispatch(id, pending) {
74
+ const { key, attempt } = pending;
75
+ if (this.#link.send({ op: attempt, id, key }))
76
+ pending.delivery = 'sent';
77
+ }
78
+ /** The caller gave up. A grant already on its way is given back by the coordinator on `cancel`. */
79
+ #withdraw(id) {
80
+ const pending = this.#take(id);
81
+ if (!pending || pending.delivery === 'sent') {
82
+ this.#link.send({ op: 'cancel', id });
83
+ }
67
84
  }
68
85
  #hold(id, key, token) {
69
86
  this.#held.set(id, { key, token });
@@ -74,40 +91,27 @@ export class RemoteLockClient {
74
91
  const wasHeld = this.#held.delete(id);
75
92
  if (this.#lost.delete(id))
76
93
  throw new LockLostError(key);
77
- if (wasHeld && this.#current) {
78
- await this.#send(this.#current, { op: 'release', id });
79
- }
94
+ // Without an open connection there is nothing to tell: the coordinator that granted the key is gone.
95
+ if (wasHeld)
96
+ this.#link.send({ op: 'release', id });
80
97
  },
81
98
  };
82
99
  }
83
- async #open() {
84
- const connection = await this.#connector.connect();
85
- if (!connection) {
86
- this.#connection = undefined;
87
- return undefined;
88
- }
89
- this.#current = connection;
90
- connection.listen({
91
- message: (response) => this.#receive(connection, response),
92
- close: () => this.#reconnect(connection),
93
- });
94
- this.#updateRef();
95
- return connection;
96
- }
97
- #receive(connection, response) {
98
- const pending = this.#pending.get(response.id);
100
+ #receive(response) {
99
101
  switch (response.op) {
100
- case 'granted':
102
+ case 'granted': {
103
+ const pending = this.#take(response.id);
101
104
  if (pending) {
102
105
  pending.answer.resolve(new FencingToken(BigInt(response.token)));
103
106
  }
104
107
  else {
105
108
  // Nobody waits for this grant any more (the request was cancelled), so give the key back.
106
- void this.#send(connection, { op: 'release', id: response.id });
109
+ this.#link.send({ op: 'release', id: response.id });
107
110
  }
108
111
  return;
112
+ }
109
113
  case 'busy':
110
- pending?.answer.resolve(undefined);
114
+ this.#take(response.id)?.answer.resolve(undefined);
111
115
  return;
112
116
  case 'rejected':
113
117
  if (this.#held.delete(response.id))
@@ -115,58 +119,54 @@ export class RemoteLockClient {
115
119
  return;
116
120
  }
117
121
  }
118
- async #send(connection, request) {
119
- try {
120
- await connection.send(request);
122
+ /** A new connection: reassert held keys first, then send what waits. */
123
+ #resume() {
124
+ // A new connection starts with its adapter's default, which may not match whether this client waits.
125
+ this.#updateRef();
126
+ for (const [id, { key, token }] of this.#held) {
127
+ this.#link.send({ op: 'reassert', id, key, token: token.toString() });
121
128
  }
122
- catch {
123
- this.#reconnect(connection);
129
+ for (const [id, pending] of this.#pending) {
130
+ // A try is one attempt; the coordinator that would have answered it is gone.
131
+ if (pending.delivery === 'stranded')
132
+ this.#take(id)?.answer.resolve(undefined);
133
+ else if (pending.delivery === 'queued')
134
+ this.#dispatch(id, pending);
124
135
  }
125
136
  }
126
- /** Disconnects for good; the coordinator releases whatever this client still holds. */
127
- close() {
128
- this.#closed = true;
129
- const current = this.#current;
130
- this.#current = undefined;
131
- current?.close();
137
+ #interrupt() {
138
+ for (const pending of this.#pending.values()) {
139
+ if (pending.delivery !== 'sent')
140
+ continue;
141
+ pending.delivery = pending.attempt === 'try' ? 'stranded' : 'queued';
142
+ }
132
143
  }
133
- #reconnect(lost) {
134
- if (this.#closed || this.#current !== lost)
135
- return;
136
- this.#current = undefined;
137
- lost.close();
138
- this.#connection = this.#open();
139
- void this.#connection.then((connection) => this.#resume(connection));
144
+ /** No coordinator heard the reassertions, so another holder may be granted the held keys. */
145
+ #fail(error) {
146
+ for (const id of this.#held.keys())
147
+ this.#lost.add(id);
148
+ this.#held.clear();
149
+ this.#rejectAll(() => error);
140
150
  }
141
- async #resume(connection) {
142
- if (!connection) {
143
- // Held keys stay exclusive: no coordinator is left to grant them to anyone else.
144
- for (const { key, answer } of this.#pending.values()) {
145
- answer.reject(new CoordinatorUnavailableError(key));
146
- }
147
- return;
148
- }
149
- for (const [id, { key, token }] of this.#held) {
150
- await this.#send(connection, {
151
- op: 'reassert',
152
- id,
153
- key,
154
- token: token.toString(),
155
- });
156
- }
157
- for (const [id, { key, attempt, answer }] of this.#pending) {
158
- // A try is one attempt; the coordinator that would have answered it is gone.
159
- if (attempt === 'try')
160
- answer.resolve(undefined);
161
- else
162
- await this.#send(connection, { op: 'acquire', id, key });
151
+ #rejectAll(reason) {
152
+ for (const [id, { key }] of this.#pending) {
153
+ this.#take(id)?.answer.reject(reason(key));
163
154
  }
164
155
  }
156
+ /** Removes a request that is about to be answered, so a late grant for it is given back. */
157
+ #take(id) {
158
+ const pending = this.#pending.get(id);
159
+ if (!pending)
160
+ return undefined;
161
+ this.#pending.delete(id);
162
+ this.#updateRef();
163
+ return pending;
164
+ }
165
165
  #updateRef() {
166
166
  if (this.#pending.size > 0)
167
- this.#current?.ref();
167
+ this.#link.ref();
168
168
  else
169
- this.#current?.unref();
169
+ this.#link.unref();
170
170
  }
171
171
  }
172
172
  //# sourceMappingURL=remote-lock-client.js.map