Skip to content

Commit

Permalink
fix disposables
Browse files Browse the repository at this point in the history
  • Loading branch information
avner committed Jun 15, 2023
1 parent 69516d7 commit b5ba53c
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 43 deletions.
8 changes: 4 additions & 4 deletions src/binary/binaryFetcher/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,24 @@ import handleActiveFile from "./activeFileHandler";
import downloadAndExtractBundle from "./bundleDownloader";
import handleExistingVersion from "./existingVersionHandler";
import {
installationState,
InstallationState,
InstallationStateEmitter,
} from "../../events/installationStateChangedEmitter";
import EventName from "../../reports/EventName";

export default async function fetchBinaryPath(): Promise<string> {
const activeVersionPath = handleActiveFile();
if (activeVersionPath) {
InstallationStateEmitter.fire(InstallationState.ExistingInstallation);
installationState.fire(InstallationState.ExistingInstallation);
return activeVersionPath;
}

const existingVersion = await handleExistingVersion();
if (existingVersion) {
InstallationStateEmitter.fire(InstallationState.ExistingInstallation);
installationState.fire(InstallationState.ExistingInstallation);
return existingVersion;
}
InstallationStateEmitter.fire(InstallationState.NewInstallation);
installationState.fire(InstallationState.NewInstallation);
return tryDownloadVersion();
}

Expand Down
12 changes: 4 additions & 8 deletions src/capabilities/capabilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,15 @@ export enum Capability {
let enabledCapabilities: Record<string, boolean> | null = null;

export function isEnabled(capability: Capability): boolean | undefined {
if (enabledCapabilities === null) {
return undefined;
}
return isCapabilityEnabled(capability);
return enabledCapabilities?.[capability];
}

export function isCapabilityEnabled(capability: Capability): boolean {
return (enabledCapabilities ?? {})[capability];
return !!enabledCapabilities?.[capability];
}

export function isAnyCapabilityEnabled(...capabilities: Capability[]): boolean {
return capabilities.some(
(capability) => (enabledCapabilities ?? {})[capability]
);
return capabilities.some((capability) => enabledCapabilities?.[capability]);
}

export function getCachedCapabilities(): string[] {
Expand Down
28 changes: 17 additions & 11 deletions src/events/installationStateChangedEmitter.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
import { Event, EventEmitter } from "vscode";
import { Disposable, Event, EventEmitter } from "vscode";

export enum InstallationState {
Undefined,
ExistingInstallation,
NewInstallation,
}

export class InstallationStateEmitter {
private static emitter = new EventEmitter<InstallationState>();
export class InstallationStateEmitter implements Disposable {
private emitter = new EventEmitter<InstallationState>();

private static internalState = InstallationState.Undefined;
private internalState = InstallationState.Undefined;

static get state(): InstallationState {
return InstallationStateEmitter.internalState;
get state(): InstallationState {
return this.internalState;
}

static fire(state: InstallationState) {
InstallationStateEmitter.internalState = state;
InstallationStateEmitter.emitter.fire(state);
fire(state: InstallationState) {
this.internalState = state;
this.emitter.fire(state);
}

static get event(): Event<InstallationState> {
return InstallationStateEmitter.emitter.event;
get event(): Event<InstallationState> {
return this.emitter.event;
}

dispose() {
this.emitter.dispose();
}
}

export const installationState = new InstallationStateEmitter();
4 changes: 4 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ import { pollUserUpdates } from "./pollUserUpdates";
import EventName from "./reports/EventName";
import registerTabnineChatWidgetWebview from "./tabnineChatWidget/tabnineChatWidgetWebview";
import { forceRegistrationIfNeeded } from "./registration/forceRegistration";
import { installationState } from "./events/installationStateChangedEmitter";
import { statePoller } from "./state/statePoller";

export async function activate(
context: vscode.ExtensionContext
Expand All @@ -59,6 +61,8 @@ export async function activate(
void initStartup(context);
context.subscriptions.push(handleSelection(context));
context.subscriptions.push(handleUninstall(() => uponUninstall(context)));
context.subscriptions.push(installationState);
context.subscriptions.push(statePoller);
registerCodeReview();

context.subscriptions.push(registerStatusBar(context));
Expand Down
4 changes: 2 additions & 2 deletions src/handlePluginInstalled.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { Disposable } from "vscode";
import { InstallationStateEmitter } from "./events/installationStateChangedEmitter";
import { installationState } from "./events/installationStateChangedEmitter";
import { openGettingStartedWebview } from "./webview/openGettingStartedWebview";
import { isAlreadyOpenedGettingStarted } from "./state/gettingStartedOpenedState";
import { ExtensionContext } from "./preRelease/types";

export default function handlePluginInstalled(
context: ExtensionContext
): Disposable {
return InstallationStateEmitter.event(() => {
return installationState.event(() => {
if (isAlreadyOpenedGettingStarted(context)) return;
openGettingStartedWebview(context);
});
Expand Down
7 changes: 2 additions & 5 deletions src/registration/forceRegistration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import {
} from "../capabilities/capabilities";
import { statePoller } from "../state/statePoller";
import {
installationState,
InstallationState,
InstallationStateEmitter,
} from "../events/installationStateChangedEmitter";
import { Publisher } from "../utils/publisher";
import { PopupTristate } from "./popupTristate";
Expand All @@ -18,7 +18,6 @@ import { fireEvent } from "../binary/requests/requests";
const isForceEnabled = new Publisher(isEnabled(Capability.FORCE_REGISTRATION));

export function shouldBlockCompletions(): boolean {
// daniel and nir said don't block completions
return false;
// if the feature is on and the user isn't logged in we will block the completions
// return (
Expand Down Expand Up @@ -74,9 +73,7 @@ function forceFlowFSM() {
});
}

if (
InstallationStateEmitter.state === InstallationState.ExistingInstallation
) {
if (installationState.state === InstallationState.ExistingInstallation) {
if (statePoller.state.currentState?.is_logged_in === false) {
void notifyState();
} else if (!statePoller.state.currentState) {
Expand Down
18 changes: 11 additions & 7 deletions src/registration/popupTristate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
// 2. not logged in
// 3. never displayed the popup before

import { EventEmitter } from "vscode";
import { Disposable, EventEmitter } from "vscode";
import {
InstallationState,
InstallationStateEmitter,
installationState,
} from "../events/installationStateChangedEmitter";
import { statePoller } from "../state/statePoller";

export class PopupTristate {
private installationState = InstallationStateEmitter.state;
export class PopupTristate implements Disposable {
private installationState = installationState.state;

private isLoggedIn = statePoller.state.currentState?.is_logged_in;

Expand All @@ -21,9 +21,9 @@ export class PopupTristate {

constructor() {
if (this.installationState === InstallationState.Undefined) {
const dispose = InstallationStateEmitter.event((e) => {
if (e !== InstallationState.Undefined) {
this.installationState = e;
const dispose = installationState.event((state) => {
if (state !== InstallationState.Undefined) {
this.installationState = state;
dispose.dispose();
this.changedStateEmitter.fire();
}
Expand Down Expand Up @@ -59,4 +59,8 @@ export class PopupTristate {
displayed() {
this.didDisplay = true;
}

dispose() {
this.changedStateEmitter.dispose();
}
}
15 changes: 12 additions & 3 deletions src/state/statePoller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Event, EventEmitter } from "vscode";
import { Disposable, Event, EventEmitter } from "vscode";
import { State } from "../binary/state";

import { BINARY_STATE_POLLING_INTERVAL_MILLISECONDS } from "../globals/consts";
Expand All @@ -9,19 +9,21 @@ export type StateEmitterProps = {
previousState: State | null | undefined;
};

export class StatePoller {
export class StatePoller implements Disposable {
private currentState: State | null | undefined;

private previousState: State | null | undefined;

private stateEmitter = new EventEmitter<StateEmitterProps>();

private intervalToken: NodeJS.Timeout | null = null;

constructor() {
void tabNineProcess.onReady.then(() => {
void getState().then((v) => {
this.currentState = v;
});
setInterval(() => {
this.intervalToken = setInterval(() => {
void getState().then((newState) => {
this.previousState = this.currentState;
this.currentState = newState;
Expand All @@ -44,6 +46,13 @@ export class StatePoller {
get event(): Event<StateEmitterProps> {
return this.stateEmitter.event;
}

dispose() {
this.stateEmitter.dispose();
if (this.intervalToken) {
clearInterval(this.intervalToken);
}
}
}

export const statePoller = new StatePoller();
6 changes: 3 additions & 3 deletions src/test/suite/gettingStarted.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import * as assert from "assert";
import { afterEach } from "mocha";
import * as sinon from "sinon";
import {
installationState,
InstallationState,
InstallationStateEmitter,
} from "../../events/installationStateChangedEmitter";
import { getContext } from "./utils/preReleaseInstaller.utils";
import handlePluginInstalled from "../../handlePluginInstalled";
Expand All @@ -21,7 +21,7 @@ suite("Getting started tests", () => {
"openGettingStartedWebview"
);
const handler = handlePluginInstalled(getContext({}));
InstallationStateEmitter.fire(InstallationState.NewInstallation);
installationState.fire(InstallationState.NewInstallation);
handler.dispose();

assert(openGettingStartedWebviewStub.calledOnce);
Expand All @@ -37,7 +37,7 @@ suite("Getting started tests", () => {
[ALREADY_OPENED_GETTING_STARTED_KEY]: true,
})
);
InstallationStateEmitter.fire(InstallationState.NewInstallation);
installationState.fire(InstallationState.NewInstallation);
handler.dispose();

assert(openGettingStartedWebviewStub.notCalled);
Expand Down

0 comments on commit b5ba53c

Please sign in to comment.