Skip to content

Commit 3ed3bf0

Browse files
committed
Release _connectLock when maxRetries reached
Fix a bug where reconnect() could not start a new connection after maxRetries was exhausted because _connectLock was not released in _connect(). Set _connectLock = false on the early return when max retries are reached. Added a test (reconnecting.test.ts) that reproduces the issue and verifies reconnect() works after retries are exhausted, and included a changeset entry documenting the patch.
1 parent 9bd3f56 commit 3ed3bf0

3 files changed

Lines changed: 43 additions & 0 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"partysocket": patch
3+
---
4+
5+
Fix `reconnect()` not working after `maxRetries` has been exhausted. The `_connectLock` was not released when the max retries early return was hit in `_connect()`, preventing any subsequent `reconnect()` call from initiating a new connection.

packages/partysocket/src/tests/reconnecting.test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -937,3 +937,40 @@ testDone("reconnect after closing", (done, fail) => {
937937
}
938938
});
939939
});
940+
941+
testDone(
942+
"reconnect() works after maxRetries has been exhausted",
943+
(done, fail) => {
944+
// Connect to an unreachable URL with maxRetries=0 so retries exhaust quickly.
945+
// This reproduces the bug where _connectLock was not released when
946+
// maxRetries was reached, preventing reconnect() from working.
947+
// (https://github.com/cloudflare/partykit/issues/252)
948+
const ws = new ReconnectingWebSocket(ERROR_URL, undefined, {
949+
maxRetries: 0,
950+
connectionTimeout: 500,
951+
minReconnectionDelay: 10,
952+
maxReconnectionDelay: 50
953+
});
954+
955+
let reconnected = false;
956+
ws.addEventListener("error", () => {
957+
if (reconnected) return;
958+
reconnected = true;
959+
960+
// maxRetries is now exhausted. Switch to the working server and reconnect.
961+
// @ts-expect-error accessing private _url for testing
962+
ws._url = URL;
963+
ws.reconnect();
964+
});
965+
966+
ws.addEventListener("open", () => {
967+
ws.close();
968+
done();
969+
});
970+
971+
setTimeout(() => {
972+
ws.close();
973+
fail(new Error("timed out waiting for reconnect after maxRetries"));
974+
}, 10000);
975+
}
976+
);

packages/partysocket/src/ws.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,7 @@ export default class ReconnectingWebSocket extends (EventTarget as TypedEventTar
455455

456456
if (this._retryCount >= maxRetries) {
457457
this._debug("max retries reached", this._retryCount, ">=", maxRetries);
458+
this._connectLock = false;
458459
return;
459460
}
460461

0 commit comments

Comments
 (0)