Skip to content

Commit 6569a60

Browse files
authored
fix(globals): use 'local' globals if not running web mode (aws#4754)
Problem: To get web tests working we used globalThis for globals. This is shared across extensions in VS Code, resulting in problems if another extension declares the same global twice. This is occurs when we run standalone and toolkit at the same time. Solution: Use local globals if we are not in web mode. Otherwise, use full globals. This allows the web tests to pass. We will have to revisit this if we have 2 extensions running in web mode. - Also add slightly more informative globals error handling. - Refactor CW class so that globals doesn't get called during imports.
1 parent cae6147 commit 6569a60

28 files changed

+128
-131
lines changed

docs/web.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,4 @@ The assumption for the behavior is due to how Web Workers work. We (VS Code) use
151151
- VS Code uses Dedicated Workers since `globalThis` is indicated as a [`DedicatedWorkerGlobalScope`](https://developer.mozilla.org/en-US/docs/Web/API/DedicatedWorkerGlobalScope) when debugging
152152
- `globalThis` is one object (that I could find so far) which **is shared** between our extension and test scripts. A guess to why is that the main script spawns another web worker (for unit tests) and passes on the `DedicatedWorkerGlobalScope`. See [`"Workers can also spawn other workers"`](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Functions_and_classes_available_to_workers).
153153
- `globalThis` returns `global` in Node.js, or a `WorkerGlobalScope` in the browser
154+
- NOTE: `globalThis` is shared across all of VS Code, including all extensions.

packages/amazonq/src/extension.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import * as vscode from 'vscode'
77
import { activateShared, deactivateShared } from './extensionShared'
88

99
export async function activate(context: vscode.ExtensionContext) {
10-
await activateShared(context)
10+
await activateShared(context, false)
1111
}
1212

1313
export async function deactivate() {

packages/amazonq/src/extensionShared.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,10 @@ import { isExtensionActive, VSCODE_EXTENSION_ID } from 'aws-core-vscode/utils'
3636
import { registerSubmitFeedback } from 'aws-core-vscode/feedback'
3737
import { telemetry, ExtStartUpSources } from 'aws-core-vscode/telemetry'
3838

39-
export async function activateShared(context: vscode.ExtensionContext) {
39+
export async function activateShared(context: vscode.ExtensionContext, isWeb: boolean) {
40+
initialize(context, isWeb)
41+
await initializeComputeRegion()
42+
4043
const contextPrefix = 'amazonq'
4144
globals.contextPrefix = 'amazonq.' //todo: disconnect from above line
4245

@@ -72,8 +75,6 @@ export async function activateShared(context: vscode.ExtensionContext) {
7275
}
7376
}
7477

75-
await initializeComputeRegion()
76-
initialize(context)
7778
const extContext = {
7879
extensionContext: context,
7980
}

packages/core/src/amazonqGumby/activation.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { ExtContext } from '../shared/extensions'
1010
import { stopTransformByQ } from '../codewhisperer/commands/startTransformByQ'
1111
import { transformByQState } from '../codewhisperer/models/model'
1212
import { ProposedTransformationExplorer } from '../codewhisperer/service/transformByQ/transformationResultsViewProvider'
13-
import { codeTransformTelemetryState } from './telemetry/codeTransformTelemetryState'
13+
import { CodeTransformTelemetryState } from './telemetry/codeTransformTelemetryState'
1414
import { telemetry } from '../shared/telemetry/telemetry'
1515
import { CancelActionPositions } from './telemetry/codeTransformTelemetry'
1616
import { AuthUtil } from '../codewhisperer/util/authUtil'
@@ -32,14 +32,14 @@ export async function activate(context: ExtContext) {
3232
if (transformByQState.isRunning()) {
3333
telemetry.codeTransform_jobIsClosedDuringIdeRun.emit({
3434
codeTransformJobId: transformByQState.getJobId(),
35-
codeTransformSessionId: codeTransformTelemetryState.getSessionId(),
35+
codeTransformSessionId: CodeTransformTelemetryState.instance.getSessionId(),
3636
codeTransformStatus: transformByQState.getStatus(),
3737
})
3838
}
3939
} else {
4040
telemetry.codeTransform_jobIsResumedAfterIdeClose.emit({
4141
codeTransformJobId: transformByQState.getJobId(),
42-
codeTransformSessionId: codeTransformTelemetryState.getSessionId(),
42+
codeTransformSessionId: CodeTransformTelemetryState.instance.getSessionId(),
4343
codeTransformStatus: transformByQState.getStatus(),
4444
})
4545
}

packages/core/src/amazonqGumby/chat/controller/controller.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import { CancelActionPositions } from '../../telemetry/codeTransformTelemetry'
3131
import { openUrl } from '../../../shared/utilities/vsCodeUtils'
3232
import { telemetry } from '../../../shared/telemetry/telemetry'
3333
import { MetadataResult } from '../../../shared/telemetry/telemetryClient'
34-
import { codeTransformTelemetryState } from '../../telemetry/codeTransformTelemetryState'
34+
import { CodeTransformTelemetryState } from '../../telemetry/codeTransformTelemetryState'
3535
import { getAuthType } from '../../../codewhisperer/service/transformByQ/transformApiHandler'
3636

3737
// These events can be interactions within the chat,
@@ -234,7 +234,7 @@ export class GumbyController {
234234
private async initiateTransformationOnProject(message: any) {
235235
const authType = await getAuthType()
236236
telemetry.codeTransform_jobIsStartedFromChatPrompt.emit({
237-
codeTransformSessionId: codeTransformTelemetryState.getSessionId(),
237+
codeTransformSessionId: CodeTransformTelemetryState.instance.getSessionId(),
238238
credentialSourceId: authType,
239239
result: MetadataResult.Pass,
240240
})

packages/core/src/amazonqGumby/telemetry/codeTransformTelemetryState.ts

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@
55

66
import { randomUUID } from '../../common/crypto'
77

8-
interface ICodeTransformerTelemetryState {
8+
interface ICodeTransformTelemetryState {
99
sessionId: string
1010
sessionStartTime: number
1111
resultStatus: string
1212
}
1313

14-
class CodeTransformerTelemetryState {
15-
private static instance: CodeTransformerTelemetryState
16-
mainState: ICodeTransformerTelemetryState
14+
export class CodeTransformTelemetryState {
15+
mainState: ICodeTransformTelemetryState
1716

1817
private constructor() {
1918
this.mainState = {
@@ -23,14 +22,6 @@ class CodeTransformerTelemetryState {
2322
}
2423
}
2524

26-
public static getInstance(): CodeTransformerTelemetryState {
27-
if (!CodeTransformerTelemetryState.instance) {
28-
CodeTransformerTelemetryState.instance = new CodeTransformerTelemetryState()
29-
}
30-
31-
return CodeTransformerTelemetryState.instance
32-
}
33-
3425
public getSessionId = () => this.mainState.sessionId
3526
public getStartTime = () => this.mainState.sessionStartTime
3627
public getResultStatus = () => this.mainState.resultStatus
@@ -44,6 +35,10 @@ class CodeTransformerTelemetryState {
4435
public setResultStatus = (newValue: string) => {
4536
this.mainState.resultStatus = newValue
4637
}
47-
}
4838

49-
export const codeTransformTelemetryState = CodeTransformerTelemetryState.getInstance()
39+
static #instance: CodeTransformTelemetryState
40+
41+
public static get instance() {
42+
return (this.#instance ??= new this())
43+
}
44+
}

packages/core/src/auth/activation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ import { ExtensionUse, initAuthCommands } from './utils'
1212
import { isCloud9 } from '../shared/extensionUtilities'
1313
import { isInDevEnv } from '../shared/vscode/env'
1414
import { registerCommands, getShowManageConnections } from './ui/vue/show'
15-
import { isWeb } from '../common/webUtils'
1615
import { UriHandler } from '../shared/vscode/uriHandler'
1716
import { authenticationPath } from './sso/ssoAccessTokenProvider'
17+
import { isWeb } from '../shared/extensionGlobals'
1818

1919
export async function initialize(
2020
extensionContext: vscode.ExtensionContext,

packages/core/src/auth/ui/vue/show.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* This module sets up the necessary components
66
* for the webview to be shown.
77
*/
8-
import globals from '../../../shared/extensionGlobals'
8+
import globals, { isWeb } from '../../../shared/extensionGlobals'
99
import { getIdeProperties, isCloud9 } from '../../../shared/extensionUtilities'
1010
import { VueWebview } from '../../../webviews/main'
1111
import * as vscode from 'vscode'
@@ -53,7 +53,6 @@ import { ClassToInterfaceType } from '../../../shared/utilities/tsUtils'
5353
import { debounce } from 'lodash'
5454
import { submitFeedback } from '../../../feedback/vue/submitFeedback'
5555
import { InvalidGrantException } from '@aws-sdk/client-sso-oidc'
56-
import { isWeb } from '../../../common/webUtils'
5756
import { ExtStartUpSources } from '../../../shared/telemetry'
5857

5958
export class AuthWebview extends VueWebview {

packages/core/src/codewhisperer/commands/startTransformByQ.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import {
3737
CodeTransformJavaTargetVersionsAllowed,
3838
telemetry,
3939
} from '../../shared/telemetry/telemetry'
40-
import { codeTransformTelemetryState } from '../../amazonqGumby/telemetry/codeTransformTelemetryState'
40+
import { CodeTransformTelemetryState } from '../../amazonqGumby/telemetry/codeTransformTelemetryState'
4141
import {
4242
CancelActionPositions,
4343
JDKToTelemetryValue,
@@ -98,7 +98,7 @@ async function validateJavaHome(): Promise<boolean> {
9898
}
9999
if (javaVersionUsedByMaven !== transformByQState.getSourceJDKVersion()) {
100100
telemetry.codeTransform_isDoubleClickedToTriggerInvalidProject.emit({
101-
codeTransformSessionId: codeTransformTelemetryState.getSessionId(),
101+
codeTransformSessionId: CodeTransformTelemetryState.instance.getSessionId(),
102102
codeTransformPreValidationError: 'ProjectJDKDiffersFromMavenJDK',
103103
result: MetadataResult.Fail,
104104
reason: `${transformByQState.getSourceJDKVersion()} (project) - ${javaVersionUsedByMaven} (maven)`,
@@ -143,7 +143,7 @@ export async function startTransformByQ() {
143143
intervalId = setInterval(() => {
144144
void vscode.commands.executeCommand(
145145
'aws.amazonq.showPlanProgressInHub',
146-
codeTransformTelemetryState.getStartTime()
146+
CodeTransformTelemetryState.instance.getStartTime()
147147
)
148148
}, CodeWhispererConstants.transformationJobPollingIntervalSeconds * 1000)
149149

@@ -276,9 +276,9 @@ export async function finalizeTransformationJob(status: string) {
276276
transformByQState.setToSucceeded()
277277
if (status === 'PARTIALLY_COMPLETED') {
278278
transformByQState.setToPartiallySucceeded()
279-
codeTransformTelemetryState.setResultStatus('JobPartiallySucceeded')
279+
CodeTransformTelemetryState.instance.setResultStatus('JobPartiallySucceeded')
280280
} else {
281-
codeTransformTelemetryState.setResultStatus('JobCompletedSuccessfully')
281+
CodeTransformTelemetryState.instance.setResultStatus('JobCompletedSuccessfully')
282282
}
283283

284284
await vscode.commands.executeCommand('aws.amazonq.transformationHub.reviewChanges.reveal')
@@ -300,7 +300,7 @@ export async function setTransformationToRunningState() {
300300
sessionPlanProgress['generatePlan'] = StepProgress.Pending
301301
sessionPlanProgress['transformCode'] = StepProgress.Pending
302302

303-
codeTransformTelemetryState.setStartTime()
303+
CodeTransformTelemetryState.instance.setStartTime()
304304

305305
const projectPath = transformByQState.getProjectPath()
306306
let projectId = telemetryUndefined
@@ -309,7 +309,7 @@ export async function setTransformationToRunningState() {
309309
}
310310

311311
telemetry.codeTransform_jobStartedCompleteFromPopupDialog.emit({
312-
codeTransformSessionId: codeTransformTelemetryState.getSessionId(),
312+
codeTransformSessionId: CodeTransformTelemetryState.instance.getSessionId(),
313313
codeTransformJavaSourceVersionsAllowed: JDKToTelemetryValue(
314314
transformByQState.getSourceJDKVersion()!
315315
) as CodeTransformJavaSourceVersionsAllowed,
@@ -323,7 +323,7 @@ export async function setTransformationToRunningState() {
323323
await vscode.commands.executeCommand('workbench.view.extension.aws-codewhisperer-transformation-hub')
324324
await vscode.commands.executeCommand(
325325
'aws.amazonq.showPlanProgressInHub',
326-
codeTransformTelemetryState.getStartTime()
326+
CodeTransformTelemetryState.instance.getStartTime()
327327
)
328328
}
329329

@@ -351,16 +351,16 @@ export async function postTransformationJob() {
351351
transformByQState
352352
.getChatControllers()
353353
?.transformationFinished.fire({ message: chatMessage, tabID: ChatSessionManager.Instance.getSession().tabID })
354-
const durationInMs = calculateTotalLatency(codeTransformTelemetryState.getStartTime())
355-
const resultStatusMessage = codeTransformTelemetryState.getResultStatus()
354+
const durationInMs = calculateTotalLatency(CodeTransformTelemetryState.instance.getStartTime())
355+
const resultStatusMessage = CodeTransformTelemetryState.instance.getResultStatus()
356356

357357
const versionInfo = await getVersionData()
358358
const mavenVersionInfoMessage = `${versionInfo[0]} (${transformByQState.getMavenName()})`
359359
const javaVersionInfoMessage = `${versionInfo[1]} (${transformByQState.getMavenName()})`
360360

361361
// Note: IntelliJ implementation of ResultStatusMessage includes additional metadata such as jobId.
362362
telemetry.codeTransform_totalRunTime.emit({
363-
codeTransformSessionId: codeTransformTelemetryState.getSessionId(),
363+
codeTransformSessionId: CodeTransformTelemetryState.instance.getSessionId(),
364364
codeTransformResultStatusMessage: resultStatusMessage,
365365
codeTransformRunTimeLatency: durationInMs,
366366
codeTransformLocalMavenVersion: mavenVersionInfoMessage,
@@ -371,7 +371,7 @@ export async function postTransformationJob() {
371371

372372
sessionJobHistory = processHistory(
373373
sessionJobHistory,
374-
convertDateToTimestamp(new Date(codeTransformTelemetryState.getStartTime())),
374+
convertDateToTimestamp(new Date(CodeTransformTelemetryState.instance.getStartTime())),
375375
transformByQState.getProjectName(),
376376
transformByQState.getStatus(),
377377
convertToTimeString(durationInMs),
@@ -402,7 +402,7 @@ export async function transformationJobErrorHandler(error: any) {
402402
if (!transformByQState.isCancelled()) {
403403
// means some other error occurred; cancellation already handled by now with stopTransformByQ
404404
transformByQState.setToFailed()
405-
codeTransformTelemetryState.setResultStatus('JobFailed')
405+
CodeTransformTelemetryState.instance.setResultStatus('JobFailed')
406406
// jobFailureErrorNotification should always be defined here
407407
let displayedErrorMessage = transformByQState.getJobFailureErrorNotification() ?? 'Job failed'
408408
if (transformByQState.getJobFailureMetadata() !== '') {
@@ -430,7 +430,7 @@ export async function cleanupTransformationJob(intervalId: NodeJS.Timeout | unde
430430
await vscode.commands.executeCommand('setContext', 'gumby.isStopButtonAvailable', false)
431431
await vscode.commands.executeCommand(
432432
'aws.amazonq.showPlanProgressInHub',
433-
codeTransformTelemetryState.getStartTime()
433+
CodeTransformTelemetryState.instance.getStartTime()
434434
)
435435
}
436436

@@ -463,7 +463,7 @@ export async function stopTransformByQ(
463463
if (transformByQState.isRunning()) {
464464
getLogger().info('CodeTransformation: User requested to stop transformation. Stopping transformation.')
465465
transformByQState.setToCancelled()
466-
codeTransformTelemetryState.setResultStatus('JobCancelled')
466+
CodeTransformTelemetryState.instance.setResultStatus('JobCancelled')
467467
await vscode.commands.executeCommand('setContext', 'gumby.isStopButtonAvailable', false)
468468
try {
469469
await stopJob(jobId)
@@ -491,7 +491,7 @@ export async function stopTransformByQ(
491491
}
492492
telemetry.codeTransform_jobIsCancelledByUser.emit({
493493
codeTransformCancelSrcComponents: cancelSrc as CodeTransformCancelSrcComponents,
494-
codeTransformSessionId: codeTransformTelemetryState.getSessionId(),
494+
codeTransformSessionId: CodeTransformTelemetryState.instance.getSessionId(),
495495
result: MetadataResult.Pass,
496496
})
497497
}

0 commit comments

Comments
 (0)