Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creates a new websocket connection in case of disconnect #219

Merged
merged 3 commits into from
Jun 8, 2023
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 41 additions & 27 deletions packages/jupyter-ai/src/chat_handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,34 +29,11 @@ export class ChatHandler implements IDisposable {
* resolved when server acknowledges connection and sends the client ID. This
* must be awaited before calling any other method.
*/
public initialize(): Promise<void> {
return new Promise<void>((resolve, reject) => {
if (this.isDisposed) {
return;
}
const { token, WebSocket, wsUrl } = this.serverSettings;
const url =
URLExt.join(wsUrl, CHAT_SERVICE_URL) +
(token ? `?token=${encodeURIComponent(token)}` : '');

const socket = (this._socket = new WebSocket(url));
socket.onerror = (e) => reject(e);
socket.onmessage = msg =>
msg.data && this._onMessage(JSON.parse(msg.data));

const listenForConnection = (message: AiService.Message) => {
if (message.type !== 'connection') {
return;
}
this.id = message.client_id;
resolve();
this.removeListener(listenForConnection);
};

this.addListener(listenForConnection);
});
public async initialize() {
await this._initialize();
}


/**
* Sends a message across the WebSocket. Promise resolves to the message ID
* when the server sends the same message back, acknowledging receipt.
Expand Down Expand Up @@ -116,7 +93,6 @@ export class ChatHandler implements IDisposable {
return;
}
this._isDisposed = true;

this._listeners = [];

// Clean up socket.
Expand Down Expand Up @@ -164,6 +140,44 @@ export class ChatHandler implements IDisposable {
(value: AiService.AgentChatMessage) => void
> = {};

private _onClose(reject: any) {
reject(new Error("Chat UI websocket disconnected"))
console.error("Chat UI websocket disconnected")
3coins marked this conversation as resolved.
Show resolved Hide resolved
const delaySeconds = 1
console.info(`Will try to reconnect in ${delaySeconds} seconds.`)
3coins marked this conversation as resolved.
Show resolved Hide resolved
setTimeout(async () => await this._initialize(), delaySeconds * 1000);
}

private _initialize(): Promise<void> {
return new Promise<void>((resolve, reject) => {
if (this.isDisposed) {
return;
}
console.log("Creating a new websocket connection for chat...");
const { token, WebSocket, wsUrl } = this.serverSettings;
const url =
URLExt.join(wsUrl, CHAT_SERVICE_URL) +
(token ? `?token=${encodeURIComponent(token)}` : '');

const socket = (this._socket = new WebSocket(url));
socket.onclose = () => this._onClose(reject);
socket.onerror = (e) => reject(e);
socket.onmessage = msg =>
msg.data && this._onMessage(JSON.parse(msg.data));

const listenForConnection = (message: AiService.Message) => {
if (message.type !== 'connection') {
return;
}
this.id = message.client_id;
resolve();
this.removeListener(listenForConnection);
};

this.addListener(listenForConnection);
3coins marked this conversation as resolved.
Show resolved Hide resolved
});
}

private _isDisposed = false;
private _socket: WebSocket | null = null;
private _listeners: ((msg: any) => void)[] = [];
Expand Down