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

View File

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

View File

@@ -37,6 +37,7 @@ describe("Variant Analysis Monitor", async function () {
let mockGetVariantAnalysis: sinon.SinonStub;
let cancellationTokenSource: CancellationTokenSource;
let variantAnalysisMonitor: VariantAnalysisMonitor;
let shouldCancelMonitor: sinon.SinonStub;
let variantAnalysis: VariantAnalysis;
let variantAnalysisManager: VariantAnalysisManager;
let mockGetDownloadResult: sinon.SinonStub;
@@ -44,6 +45,7 @@ describe("Variant Analysis Monitor", async function () {
beforeEach(async () => {
sandbox = sinon.createSandbox();
sandbox.stub(config, "isVariantAnalysisLiveResultsEnabled").returns(false);
shouldCancelMonitor = sinon.stub();
cancellationTokenSource = new CancellationTokenSource();
@@ -55,7 +57,10 @@ describe("Variant Analysis Monitor", async function () {
"GitHub.vscode-codeql",
)!
.activate();
variantAnalysisMonitor = new VariantAnalysisMonitor(extension.ctx);
variantAnalysisMonitor = new VariantAnalysisMonitor(
extension.ctx,
shouldCancelMonitor,
);
} catch (e) {
fail(e as Error);
}
@@ -112,6 +117,17 @@ describe("Variant Analysis Monitor", async function () {
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 () => {
let mockFailedApiResponse: VariantAnalysisApiResponse;