Skip to content

Commit

Permalink
fix: fixes bug where relayer could go into reconnection loop when mul…
Browse files Browse the repository at this point in the history
…tiple disconnect events are emitted at the same time
  • Loading branch information
ganchoradkov committed Aug 28, 2024
1 parent 3557a0c commit dbbf7c2
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
15 changes: 11 additions & 4 deletions packages/core/src/controllers/relayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export class Relayer extends IRelayer {
* meaning if we don't receive a message in 30 seconds, the connection can be considered dead
*/
private heartBeatTimeout = toMiliseconds(THIRTY_SECONDS + ONE_SECOND);
private reconnectTimeout: NodeJS.Timeout | undefined;

constructor(opts: RelayerOptions) {
super(opts);
Expand Down Expand Up @@ -295,9 +296,14 @@ export class Relayer extends IRelayer {
this.provider.connect(),
toMiliseconds(ONE_MINUTE),
`Socket stalled when trying to connect to ${this.relayUrl}`,
).catch((e) => {
reject(e);
});
)
.catch((e) => {
reject(e);
})
.finally(() => {
clearTimeout(this.reconnectTimeout);
this.reconnectTimeout = undefined;
});
this.subscriber.start().catch((error) => {
this.logger.error(error);
this.onDisconnectHandler();
Expand Down Expand Up @@ -536,7 +542,8 @@ export class Relayer extends IRelayer {
this.events.emit(RELAYER_EVENTS.disconnect);
this.connectionAttemptInProgress = false;
if (this.transportExplicitlyClosed) return;
setTimeout(async () => {
if (this.reconnectTimeout) return;
this.reconnectTimeout = setTimeout(async () => {
await this.transportOpen().catch((error) => this.logger.error(error));
}, toMiliseconds(RELAYER_RECONNECT_TIMEOUT));
}
Expand Down
17 changes: 17 additions & 0 deletions packages/core/test/relayer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,23 @@ describe("Relayer", () => {
// the identifier should be the same
expect(relayer.core.crypto.randomSessionIdentifier).to.eq(randomSessionIdentifier);
});
it("should connect once regardless of the number of disconnect events", async () => {
const disconnectsToEmit = 10;
let disconnectsReceived = 0;
let connectReceived = 0;
relayer.on(RELAYER_EVENTS.connect, () => {
connectReceived++;
});
relayer.on(RELAYER_EVENTS.disconnect, () => {
disconnectsReceived++;
});
await Promise.all(
Array.from(Array(disconnectsToEmit).keys()).map(() => relayer.onDisconnectHandler()),
);
await throttle(1000);
expect(connectReceived).to.eq(1);
expect(disconnectsReceived).to.eq(disconnectsToEmit);
});

it("should close transport 10 seconds after init if NOT active", async () => {
relayer = new Relayer({
Expand Down

0 comments on commit dbbf7c2

Please sign in to comment.