Skip to content

Commit 87bcff0

Browse files
authored
Merge pull request #6622 from davidwengier/RazorTelemetryDownloadTimeout
Add a timeout for downloading razor telemetry
2 parents 3dc4d84 + 3f654aa commit 87bcff0

File tree

7 files changed

+64
-28
lines changed

7 files changed

+64
-28
lines changed

l10n/bundle.l10n.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"Replace existing build and debug assets?": "Replace existing build and debug assets?",
4040
"Could not locate .NET Core project in '{0}'. Assets were not generated.": "Could not locate .NET Core project in '{0}'. Assets were not generated.",
4141
"Unable to generate assets to build and debug. {0}.": "Unable to generate assets to build and debug. {0}.",
42+
"Downloading Razor Telemetry Package": "Downloading Razor Telemetry Package",
4243
"Cannot load Razor language server because the directory was not found: '{0}'": "Cannot load Razor language server because the directory was not found: '{0}'",
4344
"Could not find '{0}' in or above '{1}'.": "Could not find '{0}' in or above '{1}'.",
4445
"Invalid trace setting for Razor language server. Defaulting to '{0}'": "Invalid trace setting for Razor language server. Defaulting to '{0}'",

src/packageManager/downloadAndInstallPackages.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ import { InstallationFailure, IntegrityCheckFailure } from '../omnisharp/logging
1515
import { mkdirpSync } from 'fs-extra';
1616
import { PackageInstallStart } from '../omnisharp/loggingEvents';
1717
import { DownloadValidator } from './isValidDownload';
18+
import { CancellationToken } from 'vscode';
1819

1920
export async function downloadAndInstallPackages(
2021
packages: AbsolutePathPackage[],
2122
provider: NetworkSettingsProvider,
2223
eventStream: EventStream,
23-
downloadValidator: DownloadValidator
24+
downloadValidator: DownloadValidator,
25+
token?: CancellationToken
2426
): Promise<boolean> {
2527
eventStream.post(new PackageInstallStart());
2628
for (const pkg of packages) {
@@ -33,7 +35,14 @@ export async function downloadAndInstallPackages(
3335
while (willTryInstallingPackage()) {
3436
count = count + 1;
3537
installationStage = 'downloadPackage';
36-
const buffer = await DownloadFile(pkg.description, eventStream, provider, pkg.url, pkg.fallbackUrl);
38+
const buffer = await DownloadFile(
39+
pkg.description,
40+
eventStream,
41+
provider,
42+
pkg.url,
43+
pkg.fallbackUrl,
44+
token
45+
);
3746
if (downloadValidator(buffer, pkg.integrity, eventStream)) {
3847
installationStage = 'installPackage';
3948
await InstallZip(buffer, pkg.description, pkg.installPath, pkg.binaries, eventStream);

src/packageManager/fileDownloader.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,20 @@ import { NestedError } from '../nestedError';
1717
import { parse as parseUrl } from 'url';
1818
import { getProxyAgent } from './proxy';
1919
import { NetworkSettingsProvider } from '../networkSettings';
20+
import { CancellationToken } from 'vscode';
2021

2122
export async function DownloadFile(
2223
description: string,
2324
eventStream: EventStream,
2425
networkSettingsProvider: NetworkSettingsProvider,
2526
url: string,
26-
fallbackUrl?: string
27+
fallbackUrl?: string,
28+
token?: CancellationToken
2729
): Promise<Buffer> {
2830
eventStream.post(new DownloadStart(description));
2931

3032
try {
31-
const buffer = await downloadFile(description, url, eventStream, networkSettingsProvider);
33+
const buffer = await downloadFile(description, url, eventStream, networkSettingsProvider, token);
3234
eventStream.post(new DownloadSuccess(` Done!`));
3335
return buffer;
3436
} catch (primaryUrlError) {
@@ -54,7 +56,8 @@ async function downloadFile(
5456
description: string,
5557
urlString: string,
5658
eventStream: EventStream,
57-
networkSettingsProvider: NetworkSettingsProvider
59+
networkSettingsProvider: NetworkSettingsProvider,
60+
token?: CancellationToken
5861
): Promise<Buffer> {
5962
const url = parseUrl(urlString);
6063
const networkSettings = networkSettingsProvider();
@@ -71,6 +74,10 @@ async function downloadFile(
7174
const buffers: any[] = [];
7275

7376
return new Promise<Buffer>((resolve, reject) => {
77+
token?.onCancellationRequested(() => {
78+
return reject(new NestedError(`Cancelled downloading ${urlString}.`));
79+
});
80+
7481
const request = https.request(options, (response) => {
7582
if (response.statusCode === 301 || response.statusCode === 302) {
7683
// Redirect - download from new location
@@ -81,7 +88,7 @@ async function downloadFile(
8188
return reject(new NestedError('Missing location'));
8289
}
8390
return resolve(
84-
downloadFile(description, response.headers.location, eventStream, networkSettingsProvider)
91+
downloadFile(description, response.headers.location, eventStream, networkSettingsProvider, token)
8592
);
8693
} else if (response.statusCode !== 200) {
8794
// Download failed - print error message

src/razor/razorTelemetryDownloader.ts

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6+
import * as vscode from 'vscode';
67
import { PlatformInformation } from '../shared/platform';
78
import { PackageInstallation, LogPlatformInfo, InstallationSuccess } from '../omnisharp/loggingEvents';
89
import { EventStream } from '../eventStream';
@@ -42,17 +43,27 @@ export class RazorTelemetryDownloader {
4243
if (packagesToInstall.length > 0) {
4344
this.eventStream.post(new PackageInstallation(`Razor Telemetry Version = ${version}`));
4445
this.eventStream.post(new LogPlatformInfo(this.platformInfo));
45-
if (
46-
await downloadAndInstallPackages(
47-
packagesToInstall,
48-
this.networkSettingsProvider,
49-
this.eventStream,
50-
isValidDownload
51-
)
52-
) {
53-
this.eventStream.post(new InstallationSuccess());
54-
return true;
55-
}
46+
await vscode.window.withProgress(
47+
{
48+
location: vscode.ProgressLocation.Notification,
49+
title: vscode.l10n.t('Downloading Razor Telemetry Package'),
50+
cancellable: true,
51+
},
52+
async (_, token) => {
53+
if (
54+
await downloadAndInstallPackages(
55+
packagesToInstall,
56+
this.networkSettingsProvider,
57+
this.eventStream,
58+
isValidDownload,
59+
token
60+
)
61+
) {
62+
this.eventStream.post(new InstallationSuccess());
63+
return true;
64+
}
65+
}
66+
);
5667
}
5768

5869
return false;

src/razor/src/extension.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import * as path from 'path';
77
import * as vscode from 'vscode';
88
import * as vscodeapi from 'vscode';
9+
import * as util from '../../common';
910
import { ExtensionContext } from 'vscode';
1011
import { BlazorDebugConfigurationProvider } from './blazorDebug/blazorDebugConfigurationProvider';
1112
import { CodeActionsHandler } from './codeActions/codeActionsHandler';
@@ -99,17 +100,27 @@ export async function activate(
99100
// Save user's DOTNET_ROOT env-var value so server can recover the user setting when needed
100101
env.DOTNET_ROOT_USER = process.env.DOTNET_ROOT ?? 'EMPTY';
101102

103+
let telemetryExtensionDllPath = '';
102104
// Set up DevKit environment for telemetry
103105
if (csharpDevkitExtension) {
104106
await setupDevKitEnvironment(env, csharpDevkitExtension, logger);
107+
108+
const telemetryExtensionPath = path.join(
109+
util.getExtensionPath(),
110+
'.razortelemetry',
111+
'Microsoft.VisualStudio.DevKit.Razor.dll'
112+
);
113+
if (await util.fileExists(telemetryExtensionPath)) {
114+
telemetryExtensionDllPath = telemetryExtensionPath;
115+
}
105116
}
106117

107118
const languageServerClient = new RazorLanguageServerClient(
108119
vscodeType,
109120
languageServerDir,
110121
razorTelemetryReporter,
111122
vscodeTelemetryReporter,
112-
csharpDevkitExtension !== undefined,
123+
telemetryExtensionDllPath,
113124
env,
114125
dotnetInfo.path,
115126
logger

src/razor/src/razorLanguageServerClient.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import * as path from 'path';
76
import * as cp from 'child_process';
87
import { EventEmitter } from 'events';
9-
import * as util from '../../common';
108
import * as vscode from 'vscode';
119
import { RequestHandler, RequestType } from 'vscode-jsonrpc';
1210
import { GenericNotificationHandler, InitializeResult, LanguageClientOptions, State } from 'vscode-languageclient';
@@ -40,7 +38,7 @@ export class RazorLanguageServerClient implements vscode.Disposable {
4038
private readonly languageServerDir: string,
4139
private readonly razorTelemetryReporter: RazorTelemetryReporter,
4240
private readonly vscodeTelemetryReporter: TelemetryReporter,
43-
private readonly isCSharpDevKitActivated: boolean,
41+
private readonly telemetryExtensionDllPath: string,
4442
private readonly env: NodeJS.ProcessEnv,
4543
private readonly dotnetExecutablePath: string,
4644
private readonly logger: RazorLogger
@@ -249,13 +247,10 @@ export class RazorLanguageServerClient implements vscode.Disposable {
249247
args.push('--UpdateBuffersForClosedDocuments');
250248
args.push('true');
251249

252-
if (this.isCSharpDevKitActivated) {
250+
if (this.telemetryExtensionDllPath.length > 0) {
253251
args.push('--telemetryLevel', this.vscodeTelemetryReporter.telemetryLevel);
254252
args.push('--sessionId', getSessionId());
255-
args.push(
256-
'--telemetryExtensionPath',
257-
path.join(util.getExtensionPath(), '.razortelemetry', 'Microsoft.VisualStudio.DevKit.Razor.dll')
258-
);
253+
args.push('--telemetryExtensionPath', this.telemetryExtensionDllPath);
259254
}
260255
}
261256

tasks/offlinePackagingTasks.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { getPackageJSON } from '../tasks/packageJson';
2828
import { createPackageAsync } from '../tasks/vsceTasks';
2929
import { isValidDownload } from '../src/packageManager/isValidDownload';
3030
import path = require('path');
31+
import { CancellationToken } from 'vscode';
3132
// There are no typings for this library.
3233
// eslint-disable-next-line @typescript-eslint/no-var-requires
3334
const argv = require('yargs').argv;
@@ -188,7 +189,8 @@ async function installDebugger(packageJSON: any, platformInfo: PlatformInformati
188189
async function installPackageJsonDependency(
189190
dependencyName: string,
190191
packageJSON: any,
191-
platformInfo: PlatformInformation
192+
platformInfo: PlatformInformation,
193+
token?: CancellationToken
192194
) {
193195
const eventStream = new EventStream();
194196
const logger = new Logger((message) => process.stdout.write(message));
@@ -203,7 +205,7 @@ async function installPackageJsonDependency(
203205
codeExtensionPath
204206
);
205207
const provider = () => new NetworkSettings('', true);
206-
if (!(await downloadAndInstallPackages(packagesToInstall, provider, eventStream, isValidDownload))) {
208+
if (!(await downloadAndInstallPackages(packagesToInstall, provider, eventStream, isValidDownload, token))) {
207209
throw Error('Failed to download package.');
208210
}
209211
}

0 commit comments

Comments
 (0)