-
Notifications
You must be signed in to change notification settings - Fork 227
Expand file tree
/
Copy pathvariant-analysis-monitor.ts
More file actions
95 lines (76 loc) · 3.54 KB
/
variant-analysis-monitor.ts
File metadata and controls
95 lines (76 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import { ExtensionContext, CancellationToken, commands, EventEmitter } from 'vscode';
import { Credentials } from '../authentication';
import { Logger } from '../logging';
import * as ghApiClient from './gh-api/gh-api-client';
import { VariantAnalysis, VariantAnalysisStatus } from './shared/variant-analysis';
import {
VariantAnalysis as VariantAnalysisApiResponse
} from './gh-api/variant-analysis';
import { VariantAnalysisMonitorResult } from './shared/variant-analysis-monitor-result';
import { processFailureReason, processUpdatedVariantAnalysis } from './variant-analysis-processor';
import { DisposableObject } from '../pure/disposable-object';
export class VariantAnalysisMonitor extends DisposableObject {
// With a sleep of 5 seconds, the maximum number of attempts takes
// us to just over 2 days worth of monitoring.
public static maxAttemptCount = 17280;
public static sleepTime = 5000;
private readonly _onVariantAnalysisChange = this.push(new EventEmitter<VariantAnalysis | undefined>());
readonly onVariantAnalysisChange = this._onVariantAnalysisChange.event;
constructor(
private readonly extensionContext: ExtensionContext,
private readonly logger: Logger
) {
super();
}
public async monitorVariantAnalysis(
variantAnalysis: VariantAnalysis,
cancellationToken: CancellationToken
): Promise<VariantAnalysisMonitorResult> {
const credentials = await Credentials.initialize(this.extensionContext);
if (!credentials) {
throw Error('Error authenticating with GitHub');
}
let variantAnalysisSummary: VariantAnalysisApiResponse;
let attemptCount = 0;
const scannedReposDownloaded: number[] = [];
while (attemptCount <= VariantAnalysisMonitor.maxAttemptCount) {
await this.sleep(VariantAnalysisMonitor.sleepTime);
if (cancellationToken && cancellationToken.isCancellationRequested) {
return { status: 'Cancelled', error: 'Variant Analysis was canceled.' };
}
variantAnalysisSummary = await ghApiClient.getVariantAnalysis(
credentials,
variantAnalysis.controllerRepoId,
variantAnalysis.id
);
if (variantAnalysisSummary.failure_reason) {
variantAnalysis.status = VariantAnalysisStatus.Failed;
variantAnalysis.failureReason = processFailureReason(variantAnalysisSummary.failure_reason);
return {
status: 'Failed',
error: `Variant Analysis has failed: ${variantAnalysisSummary.failure_reason}`,
variantAnalysis: variantAnalysis
};
}
variantAnalysis = processUpdatedVariantAnalysis(variantAnalysis, variantAnalysisSummary);
this._onVariantAnalysisChange.fire(variantAnalysis);
void this.logger.log('****** Retrieved variant analysis' + JSON.stringify(variantAnalysisSummary));
if (variantAnalysisSummary.scanned_repositories) {
variantAnalysisSummary.scanned_repositories.forEach(scannedRepo => {
if (!scannedReposDownloaded.includes(scannedRepo.repository.id) && scannedRepo.analysis_status === 'succeeded') {
void commands.executeCommand('codeQL.autoDownloadVariantAnalysisResult', scannedRepo, variantAnalysisSummary);
scannedReposDownloaded.push(scannedRepo.repository.id);
}
});
}
if (variantAnalysisSummary.status === 'completed') {
break;
}
attemptCount++;
}
return { status: 'CompletedSuccessfully', scannedReposDownloaded: scannedReposDownloaded };
}
private async sleep(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}