Skip to content

Commit 9470bc1

Browse files
committed
Move global state poller to globalState file
1 parent 1d3f6ef commit 9470bc1

File tree

3 files changed

+52
-103
lines changed

3 files changed

+52
-103
lines changed

packages/core/src/codewhisperer/region/regionProfileManager.ts

Lines changed: 3 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@ import { localize } from '../../shared/utilities/vsCodeUtils'
2424
import { IAuthProvider } from '../util/authUtil'
2525
import { Commands } from '../../shared/vscode/commands2'
2626
import { CachedResource } from '../../shared/utilities/resourceCache'
27-
import { fs } from '../../shared/fs/fs'
28-
import path from 'path'
29-
import { globalKey } from '../../shared/globalState'
27+
import { GlobalStatePoller } from '../../shared/globalState'
3028

3129
// TODO: is there a better way to manage all endpoint strings in one place?
3230
export const defaultServiceConfig: CodeWhispererConfig = {
@@ -60,7 +58,6 @@ export class RegionProfileManager {
6058
public readonly onDidChangeRegionProfile = this._onDidChangeRegionProfile.event
6159
// Store the last API results (for UI propuse) so we don't need to call service again if doesn't require "latest" result
6260
private _profiles: RegionProfile[] = []
63-
//private sharedState: SharedState
6461

6562
private readonly cache = new (class extends CachedResource<RegionProfile[]> {
6663
constructor(private readonly profileProvider: () => Promise<RegionProfile[]>) {
@@ -127,18 +124,14 @@ export class RegionProfileManager {
127124
constructor(private readonly authProvider: IAuthProvider) {
128125
const getProfileFunction = () =>
129126
globals.globalState.tryGet<{ [label: string]: RegionProfile }>('aws.amazonq.regionProfiles', Object, {})
130-
131127
const profileChangedHandler = async () => {
132128
const profile = await this.loadPersistedRegionProfle()
133129
void this._switchRegionProfile(profile[this.authProvider.profileName], 'reload')
134130
}
135131

132+
// This is a poller that handles synchornization of selected region profiles between different IDE windows.
133+
// It checks for changes in global state of region profile, invoking the change handler to switch profiles
136134
GlobalStatePoller.create(getProfileFunction, profileChangedHandler)
137-
138-
// , async () => {
139-
// void this._switchRegionProfile((await this.loadPersistedRegionProfle())[this.authProvider.profileName], 'user')
140-
// })
141-
//this.sharedState = new SharedState('aws.amazonq.regionProfiles')
142135
}
143136

144137
async getProfiles(): Promise<RegionProfile[]> {
@@ -269,8 +262,6 @@ export class RegionProfileManager {
269262
// persist to state
270263
await this.persistSelectRegionProfile()
271264

272-
//this.sharedState.updateSharedState(this._activeRegionProfile)
273-
274265
// Force status bar to reflect this change in state
275266
await Commands.tryExecute('aws.amazonq.refreshStatusBar')
276267
}
@@ -342,13 +333,6 @@ export class RegionProfileManager {
342333

343334
previousPersistedState[this.authProvider.profileName] = this.activeRegionProfile
344335
await globals.globalState.update('aws.amazonq.regionProfiles', previousPersistedState)
345-
346-
const persistedState = globals.globalState.tryGet<{ [label: string]: RegionProfile }>(
347-
'aws.amazonq.regionProfiles',
348-
Object,
349-
{}
350-
)
351-
console.log(persistedState)
352336
}
353337

354338
async generateQuickPickItem(): Promise<DataQuickPickItem<string>[]> {
@@ -392,7 +376,6 @@ export class RegionProfileManager {
392376
if (arn) {
393377
if (this.activeRegionProfile && this.activeRegionProfile.arn === arn) {
394378
this._activeRegionProfile = undefined
395-
//this.sharedState.updateSharedState(this._activeRegionProfile)
396379
}
397380

398381
const profiles = this.loadPersistedRegionProfle()
@@ -452,82 +435,3 @@ export class RegionProfileManager {
452435
return c
453436
}
454437
}
455-
456-
export class GlobalStatePoller {
457-
protected oldValue: any
458-
protected getState: Function
459-
protected changeHandler: Function
460-
461-
constructor(getState: Function, changeHandler: Function) {
462-
this.getState = getState
463-
this.changeHandler = changeHandler
464-
this.oldValue = getState()
465-
}
466-
467-
static create(getState: Function, changeHandler: () => void) {
468-
const instance = new GlobalStatePoller(getState, changeHandler)
469-
instance.poll()
470-
return instance
471-
}
472-
473-
poll() {
474-
const interval = 1000 // ms
475-
setInterval(() => {
476-
const newValue = this.getState()
477-
if (this.oldValue !== newValue) {
478-
this.oldValue = newValue
479-
this.changeHandler()
480-
}
481-
}, interval)
482-
}
483-
}
484-
485-
export class SharedState {
486-
readonly key: globalKey
487-
protected value: any
488-
readonly filePath: string
489-
490-
constructor(key: globalKey) {
491-
this.key = key
492-
this.filePath = path.join(globals.context.globalStorageUri.fsPath, `${key}.json`)
493-
}
494-
495-
static async create(key: globalKey, changeHandler: () => void) {
496-
const instance = new SharedState(key)
497-
await instance.createGlobalStateFile()
498-
const fileWatcher = instance.getSharedStateFileWatcher()
499-
fileWatcher.onDidChange(changeHandler)
500-
}
501-
502-
protected async createGlobalStateFile() {
503-
if (!(await fs.existsFile(this.filePath))) {
504-
await this.updateFile()
505-
}
506-
}
507-
508-
protected async updateFile() {
509-
await fs.writeFile(this.filePath, `${new Date().toISOString()}`, { encoding: 'utf8' })
510-
}
511-
512-
protected getSharedStateFileWatcher() {
513-
const watcher = vscode.workspace.createFileSystemWatcher(
514-
new vscode.RelativePattern(globals.context.globalStorageUri, `${this.key}.json`)
515-
)
516-
globals.context.subscriptions.push(watcher)
517-
return watcher
518-
}
519-
520-
async updateSharedState(value: any) {
521-
const persistedState = globals.globalState.tryGet<{ [label: string]: RegionProfile }>(
522-
'aws.amazonq.regionProfiles',
523-
Object,
524-
{}
525-
)
526-
console.log(persistedState)
527-
if (value === this.value && value !== undefined) {
528-
return
529-
}
530-
this.value = value
531-
await this.updateFile()
532-
}
533-
}

packages/core/src/codewhisperer/util/authUtil.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export class AuthUtil implements IAuthProvider {
9090
this.regionProfileManager.onDidChangeRegionProfile(async () => {
9191
await this.setVscodeContextProps()
9292
})
93-
lspAuth.registerCacheWatcher((event: string) => this.cacheChangedHandler(event))
93+
lspAuth.registerCacheWatcher(async (event: string) => await this.cacheChangedHandler(event))
9494
}
9595

9696
// Do NOT use this in production code, only used for testing
@@ -277,11 +277,11 @@ export class AuthUtil implements IAuthProvider {
277277
})
278278
}
279279

280-
private cacheChangedHandler(event: string) {
280+
private async cacheChangedHandler(event: string) {
281281
if (event === 'delete') {
282-
this.logout()
282+
await this.logout()
283283
} else if (event === 'create') {
284-
this.restore()
284+
await this.restore()
285285
}
286286
}
287287

packages/core/src/shared/globalState.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,3 +318,48 @@ export class GlobalState implements vscode.Memento {
318318
return all?.[id]
319319
}
320320
}
321+
322+
/**
323+
* Utility class that polls a state value at regular intervals and triggers a callback when the state changes.
324+
*
325+
* This class can be used to monitor changes in global state and react to those changes.
326+
*/
327+
export class GlobalStatePoller {
328+
protected oldValue: any
329+
protected getState: () => any
330+
protected changeHandler: () => void
331+
332+
constructor(getState: () => any, changeHandler: () => void) {
333+
this.getState = getState
334+
this.changeHandler = changeHandler
335+
this.oldValue = getState()
336+
}
337+
338+
/**
339+
* Factory method that creates and starts a GlobalStatePoller instance.
340+
*
341+
* @param getState - Function that returns the current state value to monitor, e.g. globals.globalState.tryGet
342+
* @param changeHandler - Callback function that is invoked when the state changes
343+
* @returns A new GlobalStatePoller instance that has already started polling
344+
*/
345+
static create(getState: () => any, changeHandler: () => void) {
346+
const instance = new GlobalStatePoller(getState, changeHandler)
347+
instance.poll()
348+
return instance
349+
}
350+
351+
/**
352+
* Starts polling the state value at 1 second intervals.
353+
* When a change is detected, the changeHandler callback is invoked.
354+
*/
355+
poll() {
356+
const interval = 1000 // ms
357+
setInterval(() => {
358+
const newValue = this.getState()
359+
if (this.oldValue !== newValue) {
360+
this.oldValue = newValue
361+
this.changeHandler()
362+
}
363+
}, interval)
364+
}
365+
}

0 commit comments

Comments
 (0)