Stop variant analysis monitor after removing it

This will stop the variant analysis monitor from monitoring when a
variant analysis is removed from the query history. Since the variant
analysis monitor cannot depend on the variant analysis manager (this
would create a circular dependency), a function is passed into the
variant analysis monitor for checking whether the variant analysis
should be cancelled.

This commit will also ensure that even if a variant analysis comes in
through the `onVariantAnalysisChange` callback, it won't be added to
the variant analysis map of the manager.
This commit is contained in:
Koen Vlaswinkel
2022-11-29 11:12:46 +01:00
parent a1b81d9b6f
commit ff3b6091c6
3 changed files with 43 additions and 3 deletions

View File

@@ -94,7 +94,12 @@ export class VariantAnalysisManager
private readonly variantAnalysisResultsManager: VariantAnalysisResultsManager, private readonly variantAnalysisResultsManager: VariantAnalysisResultsManager,
) { ) {
super(); super();
this.variantAnalysisMonitor = this.push(new VariantAnalysisMonitor(ctx)); this.variantAnalysisMonitor = this.push(
new VariantAnalysisMonitor(
ctx,
this.shouldCancelMonitorVariantAnalysis.bind(this),
),
);
this.variantAnalysisMonitor.onVariantAnalysisChange( this.variantAnalysisMonitor.onVariantAnalysisChange(
this.onVariantAnalysisUpdated.bind(this), this.onVariantAnalysisUpdated.bind(this),
); );
@@ -319,6 +324,12 @@ export class VariantAnalysisManager
return await fs.pathExists(filePath); return await fs.pathExists(filePath);
} }
private async shouldCancelMonitorVariantAnalysis(
variantAnalysisId: number,
): Promise<boolean> {
return !this.variantAnalyses.has(variantAnalysisId);
}
public async onVariantAnalysisUpdated( public async onVariantAnalysisUpdated(
variantAnalysis: VariantAnalysis | undefined, variantAnalysis: VariantAnalysis | undefined,
): Promise<void> { ): Promise<void> {
@@ -326,6 +337,10 @@ export class VariantAnalysisManager
return; return;
} }
if (!this.variantAnalyses.has(variantAnalysis.id)) {
return;
}
await this.setVariantAnalysis(variantAnalysis); await this.setVariantAnalysis(variantAnalysis);
this._onVariantAnalysisStatusUpdated.fire(variantAnalysis); this._onVariantAnalysisStatusUpdated.fire(variantAnalysis);
} }

View File

@@ -29,7 +29,12 @@ export class VariantAnalysisMonitor extends DisposableObject {
); );
readonly onVariantAnalysisChange = this._onVariantAnalysisChange.event; readonly onVariantAnalysisChange = this._onVariantAnalysisChange.event;
constructor(private readonly extensionContext: ExtensionContext) { constructor(
private readonly extensionContext: ExtensionContext,
private readonly shouldCancelMonitor: (
variantAnalysisId: number,
) => Promise<boolean>,
) {
super(); super();
} }
@@ -52,6 +57,10 @@ export class VariantAnalysisMonitor extends DisposableObject {
return { status: "Canceled" }; return { status: "Canceled" };
} }
if (await this.shouldCancelMonitor(variantAnalysis.id)) {
return { status: "Canceled" };
}
const variantAnalysisSummary = await ghApiClient.getVariantAnalysis( const variantAnalysisSummary = await ghApiClient.getVariantAnalysis(
credentials, credentials,
variantAnalysis.controllerRepo.id, variantAnalysis.controllerRepo.id,

View File

@@ -37,6 +37,7 @@ describe("Variant Analysis Monitor", async function () {
let mockGetVariantAnalysis: sinon.SinonStub; let mockGetVariantAnalysis: sinon.SinonStub;
let cancellationTokenSource: CancellationTokenSource; let cancellationTokenSource: CancellationTokenSource;
let variantAnalysisMonitor: VariantAnalysisMonitor; let variantAnalysisMonitor: VariantAnalysisMonitor;
let shouldCancelMonitor: sinon.SinonStub;
let variantAnalysis: VariantAnalysis; let variantAnalysis: VariantAnalysis;
let variantAnalysisManager: VariantAnalysisManager; let variantAnalysisManager: VariantAnalysisManager;
let mockGetDownloadResult: sinon.SinonStub; let mockGetDownloadResult: sinon.SinonStub;
@@ -44,6 +45,7 @@ describe("Variant Analysis Monitor", async function () {
beforeEach(async () => { beforeEach(async () => {
sandbox = sinon.createSandbox(); sandbox = sinon.createSandbox();
sandbox.stub(config, "isVariantAnalysisLiveResultsEnabled").returns(false); sandbox.stub(config, "isVariantAnalysisLiveResultsEnabled").returns(false);
shouldCancelMonitor = sinon.stub();
cancellationTokenSource = new CancellationTokenSource(); cancellationTokenSource = new CancellationTokenSource();
@@ -55,7 +57,10 @@ describe("Variant Analysis Monitor", async function () {
"GitHub.vscode-codeql", "GitHub.vscode-codeql",
)! )!
.activate(); .activate();
variantAnalysisMonitor = new VariantAnalysisMonitor(extension.ctx); variantAnalysisMonitor = new VariantAnalysisMonitor(
extension.ctx,
shouldCancelMonitor,
);
} catch (e) { } catch (e) {
fail(e as Error); fail(e as Error);
} }
@@ -112,6 +117,17 @@ describe("Variant Analysis Monitor", async function () {
expect(result).to.eql({ status: "Canceled" }); expect(result).to.eql({ status: "Canceled" });
}); });
it("should return early if variant analysis should be cancelled", async () => {
shouldCancelMonitor.resolves(true);
const result = await variantAnalysisMonitor.monitorVariantAnalysis(
variantAnalysis,
cancellationTokenSource.token,
);
expect(result).to.eql({ status: "Canceled" });
});
describe("when the variant analysis fails", async () => { describe("when the variant analysis fails", async () => {
let mockFailedApiResponse: VariantAnalysisApiResponse; let mockFailedApiResponse: VariantAnalysisApiResponse;