Skip to content

Commit 76e73c9

Browse files
committed
add timeout
1 parent 0db69a8 commit 76e73c9

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

src/common/telemetry/constants.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ export enum EventNames {
5858
* - errorType: string (classified error category from classifyError)
5959
*/
6060
MANAGER_REGISTRATION_FAILED = 'MANAGER_REGISTRATION.FAILED',
61+
/**
62+
* Telemetry event fired when the setup block appears to be hung.
63+
* A watchdog timer fires after a deadline; if the setup completes normally,
64+
* the timer is cancelled and this event never fires.
65+
* Properties:
66+
* - failureStage: string (which phase was in progress when the watchdog fired)
67+
*/
68+
SETUP_HANG_DETECTED = 'SETUP.HANG_DETECTED',
6169
}
6270

6371
// Map all events to their properties
@@ -265,4 +273,14 @@ export interface IEventNamePropertyMapping {
265273
managerName: string;
266274
errorType: string;
267275
};
276+
277+
/* __GDPR__
278+
"setup.hang_detected": {
279+
"failureStage": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "owner": "eleanorjboyd" },
280+
"<duration>": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true, "owner": "eleanorjboyd" }
281+
}
282+
*/
283+
[EventNames.SETUP_HANG_DETECTED]: {
284+
failureStage: string;
285+
};
268286
}

src/extension.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,25 @@ export async function activate(context: ExtensionContext): Promise<PythonEnviron
524524
*/
525525
setImmediate(async () => {
526526
let failureStage = 'nativeFinder';
527+
// Watchdog: fires if setup hasn't completed within 120s, indicating a likely hang
528+
const SETUP_HANG_TIMEOUT_MS = 120_000;
529+
let hangWatchdogActive = true;
530+
const clearHangWatchdog = () => {
531+
if (!hangWatchdogActive) {
532+
return;
533+
}
534+
hangWatchdogActive = false;
535+
clearTimeout(hangWatchdog);
536+
};
537+
const hangWatchdog = setTimeout(() => {
538+
if (!hangWatchdogActive) {
539+
return;
540+
}
541+
hangWatchdogActive = false;
542+
traceError(`Setup appears hung during stage: ${failureStage}`);
543+
sendTelemetryEvent(EventNames.SETUP_HANG_DETECTED, start.elapsedTime, { failureStage });
544+
}, SETUP_HANG_TIMEOUT_MS);
545+
context.subscriptions.push({ dispose: clearHangWatchdog });
527546
try {
528547
// This is the finder that is used by all the built in environment managers
529548
const nativeFinder: NativePythonFinder = await createNativePythonFinder(outputChannel, api, context);
@@ -566,6 +585,7 @@ export async function activate(context: ExtensionContext): Promise<PythonEnviron
566585
sendTelemetryEvent(EventNames.EXTENSION_MANAGER_REGISTRATION_DURATION, start.elapsedTime, {
567586
result: 'success',
568587
});
588+
clearHangWatchdog();
569589
try {
570590
await terminalManager.initialize(api);
571591
sendManagerSelectionTelemetry(projectManager);
@@ -578,6 +598,7 @@ export async function activate(context: ExtensionContext): Promise<PythonEnviron
578598
traceError('Post-initialization tasks failed:', postInitError);
579599
}
580600
} catch (error) {
601+
clearHangWatchdog();
581602
traceError('Failed to initialize environment managers:', error);
582603
sendTelemetryEvent(
583604
EventNames.EXTENSION_MANAGER_REGISTRATION_DURATION,

0 commit comments

Comments
 (0)