Skip to content

Commit 7b014ed

Browse files
committed
Slim unnecessary comments
1 parent 462141e commit 7b014ed

File tree

4 files changed

+26
-68
lines changed

4 files changed

+26
-68
lines changed

spec/MultiTabWorkerBroker.spec.ts

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -745,42 +745,6 @@ describe("MultiTabWorkerBroker", () => {
745745
await broker2.stop();
746746
});
747747

748-
it("should handle concurrent requests with same ID from same broker", async () => {
749-
const lockName = getLockName();
750-
const broker1 = new MultiTabWorkerBroker(lockName, makeWorker);
751-
752-
const messages1: any[] = [];
753-
const conn1 = broker1.createConnection();
754-
conn1.reader.listen((msg) => messages1.push(msg));
755-
756-
await broker1.start();
757-
758-
// Send two concurrent requests with the same ID (unusual but possible)
759-
const promise1 = conn1.writer.write({
760-
jsonrpc: "2.0",
761-
id: 1,
762-
method: "add",
763-
params: { a: 1, b: 1 },
764-
} as any);
765-
766-
const promise2 = conn1.writer.write({
767-
jsonrpc: "2.0",
768-
id: 1,
769-
method: "add",
770-
params: { a: 2, b: 2 },
771-
} as any);
772-
773-
await Promise.all([promise1, promise2]);
774-
await new Promise((resolve) => setTimeout(resolve, 50));
775-
776-
// Should have received both responses
777-
expect(messages1.length).toBe(2);
778-
expect(messages1).toContainEqual(expect.objectContaining({ id: 1, result: 2 }));
779-
expect(messages1).toContainEqual(expect.objectContaining({ id: 1, result: 4 }));
780-
781-
await broker1.stop();
782-
});
783-
784748
it("should handle sequential requests with correct ordering", async () => {
785749
const lockName = getLockName();
786750
const broker1 = new MultiTabWorkerBroker(lockName, makeWorker);
@@ -1095,7 +1059,7 @@ describe("MultiTabWorkerBroker", () => {
10951059

10961060
expect(broker.isLeader).toBe(true);
10971061

1098-
broker.dispose();
1062+
await broker.stop();
10991063

11001064
// Give time for cleanup
11011065
await new Promise((resolve) => setTimeout(resolve, 10));

spec/test-worker-lsp-like.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,3 @@ self.addEventListener("message", (event: MessageEvent) => {
4242
self.postMessage(message);
4343
}
4444
});
45-
46-

src/MultiTabWorkerBroker.ts

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -38,27 +38,29 @@ export class MultiTabWorkerBroker {
3838
private workerReadyResolver: (() => void) | null = null;
3939
// Map rewritten JSONRPC IDs back to original IDs
4040
private rewrittenIdMap = new Map<string, string | number>();
41-
// Sequence number to ensure each rewritten ID is unique even if original IDs are reused
42-
private rewriteSequence = 0;
4341
// Track all active connections (reader/writer pairs)
4442
private connections = new Map<string, { reader: MultiTabMessageReader; writer: MultiTabMessageWriter }>();
4543
private nextConnectionId = 0;
44+
private shouldDebug = false;
4645

4746
constructor(
4847
private readonly lockName: string,
4948
private readonly makeWorker: () => Worker | Promise<Worker>,
50-
options?: { timeout?: number; onStateChange?: (state: { isLeader: boolean }) => void }
49+
options?: { timeout?: number; onStateChange?: (state: { isLeader: boolean }) => void; debug?: boolean }
5150
) {
5251
this.brokerId = generateBrokerId();
5352
this.timeout = options?.timeout ?? 20_000;
5453
this.onStateChange = options?.onStateChange;
54+
this.shouldDebug = options?.debug ?? false;
5555
}
5656

5757
/** Central debug logging function */
5858
private debug(message: string, ...args: any[]): void {
59-
const role = this.isLeader ? "LEADER" : "FOLLOWER";
60-
const prefix = `[MTB:${this.brokerId.slice(0, 20)}:${role}]`;
61-
console.debug(prefix, message, ...args);
59+
if (this.shouldDebug) {
60+
const role = this.isLeader ? "LEADER" : "FOLLOWER";
61+
const prefix = `[MTB:${this.brokerId.slice(0, 20)}:${role}]`;
62+
console.debug(prefix, message, ...args);
63+
}
6264
}
6365

6466
/** Central error logging function */
@@ -158,8 +160,10 @@ export class MultiTabWorkerBroker {
158160
if (!acquiredLock) {
159161
// We're a follower - the leader exists elsewhere
160162
this.isLeader = false;
163+
161164
// Set up abort controller for the follower's lock request
162165
this.lockAbortController = new AbortController();
166+
163167
// Try to acquire the lock in the background for failover
164168
this.waitForLockAndBecomeLeader();
165169

@@ -241,12 +245,11 @@ export class MultiTabWorkerBroker {
241245
/** Rewrite a JSONRPC ID to make it globally unique */
242246
private rewriteId(originalId: string | number): string {
243247
// Include a sequence number to handle ID reuse
244-
const rewrittenId = `${this.brokerId}:${this.rewriteSequence++}:${originalId}`;
248+
const rewrittenId = `${this.brokerId}:${originalId}`;
245249
this.rewrittenIdMap.set(rewrittenId, originalId);
246250
return rewrittenId;
247251
}
248252

249-
/** Un-rewrite a JSONRPC ID back to its original form */
250253
private unrewriteId(rewrittenId: string | number): { originalId: string | number; isOurs: boolean } {
251254
// Check if this ID is one of ours
252255
if (typeof rewrittenId === "string" && rewrittenId.startsWith(`${this.brokerId}:`)) {
@@ -259,7 +262,6 @@ export class MultiTabWorkerBroker {
259262
return { originalId: rewrittenId, isOurs: false };
260263
}
261264

262-
/** Rewrite message IDs if present */
263265
private rewriteMessage(message: Message): Message {
264266
// Only rewrite IDs for client->worker requests (messages with a method)
265267
// Responses (no method) must keep the original ID so the worker can match them
@@ -276,7 +278,6 @@ export class MultiTabWorkerBroker {
276278
return message;
277279
}
278280

279-
/** Un-rewrite message IDs if present and they belong to us */
280281
private unrewriteMessage(message: Message): { message: Message; isOurs: boolean } {
281282
if (message && typeof message === "object" && "id" in message && message.id !== undefined) {
282283
const { originalId, isOurs } = this.unrewriteId(message.id as string | number);
@@ -323,22 +324,19 @@ export class MultiTabWorkerBroker {
323324
}
324325
}
325326

326-
/** Emit a message to all active connections */
327327
private emitToAllConnections(message: Message): void {
328328
for (const { reader } of this.connections.values()) {
329329
reader._emitMessage(message);
330330
}
331331
}
332332

333-
/** Emit an error to all active connections */
334333
private emitErrorToAllConnections(error: Error): void {
335334
for (const { reader, writer } of this.connections.values()) {
336335
reader._emitError(error);
337336
writer._emitError(error);
338337
}
339338
}
340339

341-
/** Emit close event to all active connections */
342340
private emitCloseToAllConnections(): void {
343341
for (const { reader, writer } of this.connections.values()) {
344342
reader._emitClose();
@@ -512,11 +510,6 @@ export class MultiTabWorkerBroker {
512510
this.onStateChange?.({ isLeader: false });
513511
}
514512
}
515-
516-
/** Dispose the broker */
517-
dispose(): void {
518-
void this.stop();
519-
}
520513
}
521514

522515
class MultiTabMessageReader implements MessageReader {
@@ -550,7 +543,6 @@ class MultiTabMessageReader implements MessageReader {
550543
return disposable;
551544
}
552545

553-
/** Internal method to emit a message to all listeners */
554546
_emitMessage(message: Message): void {
555547
if (!this.disposed) {
556548
if (this.hasListener) {
@@ -566,14 +558,12 @@ class MultiTabMessageReader implements MessageReader {
566558
}
567559
}
568560

569-
/** Internal method to emit an error to all listeners */
570561
_emitError(error: Error): void {
571562
if (!this.disposed) {
572563
this.errorEmitter.fire(error);
573564
}
574565
}
575566

576-
/** Internal method to emit close event to all listeners */
577567
_emitClose(): void {
578568
if (!this.disposed) {
579569
this.closeEmitter.fire();
@@ -621,19 +611,16 @@ class MultiTabMessageWriter implements MessageWriter {
621611
// Not needed for broker communication
622612
}
623613

624-
/** Internal method to set the write handler */
625614
_setWriteHandler(handler: (message: Message) => Promise<void>): void {
626615
this.writeHandler = handler;
627616
}
628617

629-
/** Internal method to emit an error to all listeners */
630618
_emitError(error: Error): void {
631619
if (!this.disposed) {
632620
this.errorEmitter.fire([error, undefined, undefined]);
633621
}
634622
}
635623

636-
/** Internal method to emit close event to all listeners */
637624
_emitClose(): void {
638625
if (!this.disposed) {
639626
this.closeEmitter.fire();

testapp/main.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,23 @@ const broker = new MultiTabWorkerBroker("opfs-worker-lock", async () => {
2020
// Start listening
2121
initConnection.listen();
2222

23-
// Initialize the worker
24-
await initConnection.sendRequest(InitializeRequest, { arena });
23+
try {
24+
// Initialize the worker with a reasonable timeout
25+
await initConnection.sendRequest(InitializeRequest, { arena });
2526

26-
// Dispose the temporary connection (but keep the worker running)
27-
initConnection.dispose();
27+
// Give a moment for any pending messages to be processed
28+
await new Promise(resolve => setTimeout(resolve, 10));
29+
30+
// Dispose the temporary connection (but keep the worker running)
31+
initConnection.dispose();
32+
} catch (error) {
33+
// If initialization fails, clean up the worker
34+
worker.terminate();
35+
throw error;
36+
}
2837

2938
return worker;
30-
});
39+
}, { debug: true });
3140

3241
// Create a connection from the broker
3342
const brokerConnection = broker.createConnection();

0 commit comments

Comments
 (0)