Skip to content

Commit

Permalink
Improvements to reconnect flow
Browse files Browse the repository at this point in the history
Signed-off-by: worksofliam <[email protected]>
  • Loading branch information
worksofliam committed Dec 3, 2024
1 parent 2f87b30 commit 5b85d7f
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 36 deletions.
25 changes: 9 additions & 16 deletions src/api/IBMi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ export default class IBMi {
/**
* @returns {Promise<{success: boolean, error?: any}>} Was succesful at connecting or not.
*/
async connect(connectionObject: ConnectionData, reconnecting?: boolean, reloadServerSettings: boolean = false, onConnectedOperations: Function[] = [], timeoutCallback?: () => Promise<void>): Promise<ConnectionResult> {
async connect(connectionObject: ConnectionData, reconnecting?: boolean, reloadServerSettings: boolean = false, onConnectedOperations: Function[] = [], timeoutCallback?: (conn: IBMi) => Promise<void>): Promise<ConnectionResult> {
const currentExtensionVersion = process.env.VSCODEIBMI_VERSION;
try {
connectionObject.keepaliveInterval = 35000;
Expand Down Expand Up @@ -286,7 +286,7 @@ export default class IBMi {
const timeoutCallbackWrapper = () => {
// Don't call the callback function if it was based on a user cancellation request.
if (!cancelToken.isCancellationRequested) {
timeoutCallback();
timeoutCallback(this);
}
}

Expand Down Expand Up @@ -1095,15 +1095,9 @@ export default class IBMi {
});

} catch (e: any) {
this.dispose();
if (reconnecting && await vscode.window.showWarningMessage(`Could not reconnect`, {
modal: true,
detail: `Reconnection has failed. Would you like to try again?\n\n${e}`
}, `Yes`)) {
return this.connect(connectionObject, true);
}
this.disconnect();

let error = e;
let error = e.message;
if (e.code === "ENOTFOUND") {
error = `Host is unreachable. Check the connection's hostname/IP address.`;
}
Expand Down Expand Up @@ -1241,19 +1235,16 @@ export default class IBMi {
this.commandsExecuted += 1;
}

private async disconnect() {
if (this.client) {
private disconnect() {
if (this.client.connection) {
this.client.connection?.removeAllListeners();
this.client.dispose();
this.client.connection = null;
}
instance.fire(`disconnected`);
}

async dispose() {
if (this.client.connection) {
this.disconnect();
}
this.disconnect();

if (this.outputChannel) {
this.outputChannel.hide();
Expand All @@ -1263,6 +1254,8 @@ export default class IBMi {
if (this.outputChannelContent !== undefined) {
this.outputChannelContent = undefined;
}

instance.fire(`disconnected`);
}

/**
Expand Down
64 changes: 44 additions & 20 deletions src/api/Instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,35 +37,56 @@ export default class Instance {

let result: ConnectionResult;

const timeoutHandler = async () => {
if (connection) {
const timeoutHandler = async (conn: IBMi) => {
if (conn) {
const choice = await vscode.window.showWarningMessage(`Connection lost`, {
modal: true,
detail: `Connection has dropped. Would you like to reconnect?`
}, `Yes`);
detail: `Connection to ${conn.currentConnectionName} has dropped. Would you like to reconnect?`
}, `Yes`, `No, get logs`);

let disconnect = true;
if (choice === `Yes`) {
disconnect = !(await this.connect({...options, reconnecting: true})).success;
let reconnect = choice === `Yes`;
let collectLogs = choice === `No, get logs`;

if (collectLogs) {
const logs = conn.getOutputChannelContent();
vscode.workspace.openTextDocument({ content: logs, language: `plaintext` }).then(doc => {
vscode.window.showTextDocument(doc);
});
}

if (disconnect) {
this.disconnect();
};
await conn.dispose();

if (reconnect) {
await this.connect({...options, reconnecting: true});
}
}
};

return Tools.withContext("code-for-ibmi:connecting", async () => {
try {
result = await connection.connect(options.data, options.reconnecting, options.reloadServerSettings, options.onConnectedOperations || [], timeoutHandler);
} catch (e: any) {
result = { success: false, error: e.message };
}
while (true) {
try {
result = await connection.connect(options.data, options.reconnecting, options.reloadServerSettings, options.onConnectedOperations || [], timeoutHandler);
} catch (e: any) {
result = { success: false, error: e.message };
}

if (result.success) {
await this.setConnection(connection);
} else {
await this.setConnection();
if (result.success) {
await this.setConnection(connection);

} else {
await this.setConnection();
if (options.reconnecting && await vscode.window.showWarningMessage(`Could not reconnect`, {
modal: true,
detail: `Reconnection has failed. Would you like to try again?\n\n${result.error || `No error provided.`}`
}, `Yes`)) {

options.reconnecting = true;
continue;

} else {
break;
}
}
}

return result;
Expand All @@ -88,8 +109,11 @@ export default class Instance {
}

private async setConnection(connection?: IBMi) {

if (connection) {
if (this.connection) {
await this.connection.dispose();
}

this.connection = connection;
this.storage.setConnectionName(connection.currentConnectionName);
await GlobalStorage.get().setLastConnection(connection.currentConnectionName);
Expand Down

0 comments on commit 5b85d7f

Please sign in to comment.