Skip to content

Conversation

@EhabY
Copy link
Collaborator

@EhabY EhabY commented Nov 17, 2025

Closes #595

This PR implements a reconnecting WebSocket with exponential backoff that automatically uses the most up-to-date authentication information.

Why not use existing packages?

Third-party reconnecting WebSocket packages (e.g., reconnecting-websocket) were considered but don't meet our requirements:

  • Most packages are stale/unmaintained
  • None support custom async authentication methods (we pass different options based on header commands or session tokens)
  • Limited flexibility for future authentication expansion

Additional features:

  • Automatic reconnection when session tokens or host values change, ensuring we always use current authentication info
  • Potential future enhancement: Reconnect on proxy/auth/header setting changes (deferred for now)

@EhabY EhabY force-pushed the reconnecting-websockets branch 2 times, most recently from 8529e15 to 5a28ca8 Compare November 19, 2025 13:38
@EhabY EhabY force-pushed the reconnecting-websockets branch from 5a28ca8 to f10c59b Compare November 21, 2025 09:10
@EhabY EhabY force-pushed the reconnecting-websockets branch from f10c59b to 656bb4c Compare November 21, 2025 09:49
Comment on lines 193 to 196
// Don't reconnect on normal closure
if (event.code === 1000 || event.code === 1001) {
return;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: magic numbers are magic.. const these?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines +56 to +59
if (watcher.error !== undefined) {
watcher.error = undefined;
onChange.fire(null);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the context behind this change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we reach this place in the code that means we didn't encounter an error while parsing the message and thus we have a valid message so we clear the error (if any). The clients of this method usually display the error (if it exists) before attempting to access the value

Comment on lines +55 to +57
initialBackoffMs: options.initialBackoffMs ?? 250,
maxBackoffMs: options.maxBackoffMs ?? 30000,
jitterFactor: options.jitterFactor ?? 0.1,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How did we come up with these default values? This is non-blocking, just curious 😄

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh very random and some AI "researched" values hahaha

wasClean: true,
type: "close",
target: this.#currentSocket,
} as CloseEvent);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need as CloseEvent? Could we make use of satisfies?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing this out, this exposed a bigger issue with types, I made sure to narrow the types in eventStreamConnection so it's reflects the information we have and we don't do some nasty casting

* Better error handling for HTTP errors
* Refactor magic numbers
* Use strict types and avoid casting
Copy link
Collaborator

@DanielleMaywood DanielleMaywood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy with this change, thanks for addressing the types issue 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add automatic WebSocket reconnection with exponential backoff

3 participants