Skip to content

Commit

Permalink
Only trigger language server auto update once (#623)
Browse files Browse the repository at this point in the history
Previously the extension would trigger a new auto-update whenever it was
activated. However this can causes issues when a user deactivates-activates the
language server quickly multiple times, as it cause multiple timeouts to be
created. Additionally, when disabled, it would not clear any active timeouts.

This commit adds a small wrapper around the setTimeout function to track usage.
In particular, it will silently ignore calls to add a timeout if a timeout is
already active.  This commit also clears any timeouts when the language server
is disabled.
  • Loading branch information
glennsarti authored May 17, 2021
1 parent c1bdbf7 commit 967ea7b
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 2 deletions.
9 changes: 7 additions & 2 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ import {
prunedFolderNames,
sortedWorkspaceFolders
} from './vscodeUtils';
import { sleep } from './utils';
import {
SingleInstanceTimeout,
sleep
} from './utils';

interface terraformLanguageClient {
commandPrefix: string,
Expand All @@ -40,6 +43,7 @@ const appInsightsKey = '885372d2-6f3c-499f-9d25-b8b219983a52';
let reporter: TelemetryReporter;

let installPath: string;
let languageServerUpdater = new SingleInstanceTimeout();

export async function activate(context: vscode.ExtensionContext): Promise<any> {
const extensionVersion = vscode.extensions.getExtension(extensionId).packageJSON.version;
Expand Down Expand Up @@ -70,6 +74,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<any> {
const current = config('terraform').get('languageServer');
await config('terraform').update('languageServer', Object.assign(current, { external: false }), vscode.ConfigurationTarget.Global);
}
languageServerUpdater.clear();
return stopClients();
}),
vscode.commands.registerCommand('terraform.apply', async () => {
Expand Down Expand Up @@ -168,7 +173,7 @@ export function deactivate(): Promise<void[]> {

async function updateLanguageServer() {
const delay = 1000 * 60 * 60 * 24;
setTimeout(updateLanguageServer, delay); // check for new updates every 24hrs
languageServerUpdater.timeout(updateLanguageServer, delay); // check for new updates every 24hrs

// skip install if a language server binary path is set
if (!config('terraform').get('languageServer.pathToBinary')) {
Expand Down
19 changes: 19 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,22 @@ export function httpsRequest(url: string, options: https.RequestOptions = {}, en
export async function sleep(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}

// A small wrapper around setTimeout which ensures that only a single timeout
// timer can be running at a time. Attempts to add a new timeout silently fail.
export class SingleInstanceTimeout {
private timerLock = false;
private timerId: NodeJS.Timeout;

public timeout(fn, delay, ...args) {
if (!this.timerLock) {
this.timerLock = true;
this.timerId = setTimeout(function () { this.timerLock = false; fn() }, delay, args)
}
}

public clear() {
if (this.timerId) { clearTimeout(this.timerId) }
this.timerLock = false;
}
}

0 comments on commit 967ea7b

Please sign in to comment.