@@ -26,6 +26,8 @@ import { FileResourceFetcher } from '../shared/resourcefetcher/fileResourceFetch
2626import { isAmazonQ } from '../shared/extensionUtilities'
2727import { telemetry } from '../shared/telemetry/telemetry'
2828
29+ const logger = getLogger ( 'notifications' )
30+
2931/**
3032 * Handles fetching and maintaining the state of in-IDE notifications.
3133 * Notifications are constantly polled from a known endpoint and then stored in global state.
@@ -39,8 +41,6 @@ import { telemetry } from '../shared/telemetry/telemetry'
3941 * Emergency notifications - fetched at a regular interval.
4042 */
4143export class NotificationsController {
42- public static readonly suggestedPollIntervalMs = 1000 * 60 * 10 // 10 minutes
43-
4444 /** Internal memory state that is written to global state upon modification. */
4545 private readonly state : NotificationsState
4646
@@ -75,7 +75,7 @@ export class NotificationsController {
7575 this . readState ( )
7676 await this . fetchNotifications ( category )
7777 } catch ( err : any ) {
78- getLogger ( 'notifications' ) . error ( `Unable to fetch %s notifications: %s` , category , err )
78+ logger . error ( `Unable to fetch %s notifications: %s` , category , err )
7979 }
8080
8181 await this . displayNotifications ( ruleEngine )
@@ -121,7 +121,9 @@ export class NotificationsController {
121121 * hide all notifications.
122122 */
123123 public async dismissNotification ( notificationId : string ) {
124- getLogger ( 'notifications' ) . debug ( 'Dismissing notification: %s' , notificationId )
124+ logger . debug ( 'Dismissing notification: %s' , notificationId )
125+
126+ this . readState ( ) // Don't overwrite dismissals from other windows
125127 this . state . dismissed . push ( notificationId )
126128 await this . writeState ( )
127129
@@ -134,7 +136,7 @@ export class NotificationsController {
134136 private async fetchNotifications ( category : NotificationType ) {
135137 const response = await this . fetcher . fetch ( category , this . state [ category ] . eTag )
136138 if ( ! response . content ) {
137- getLogger ( 'notifications' ) . verbose ( 'No new notifications for category: %s' , category )
139+ logger . verbose ( 'No new notifications for category: %s' , category )
138140 return
139141 }
140142 // Parse the notifications
@@ -149,7 +151,7 @@ export class NotificationsController {
149151 const addedNotifications = newNotifications . filter ( ( n : any ) => ! currentNotificationIds . has ( n . id ) )
150152
151153 if ( addedNotifications . length > 0 ) {
152- getLogger ( 'notifications' ) . verbose (
154+ logger . verbose (
153155 'New notifications received for category %s, ids: %s' ,
154156 category ,
155157 addedNotifications . map ( ( n : any ) => n . id ) . join ( ', ' )
@@ -161,7 +163,7 @@ export class NotificationsController {
161163 this . state [ category ] . eTag = response . eTag
162164 await this . writeState ( )
163165
164- getLogger ( 'notifications' ) . verbose (
166+ logger . verbose (
165167 "Fetched notifications JSON for category '%s' with schema version: %s. There were %d notifications." ,
166168 category ,
167169 this . state [ category ] . payload ?. schemaVersion ,
@@ -173,7 +175,7 @@ export class NotificationsController {
173175 * Write the latest memory state to global state.
174176 */
175177 private async writeState ( ) {
176- getLogger ( 'notifications' ) . debug ( 'NotificationsController: Updating notifications state at %s' , this . storageKey )
178+ logger . debug ( 'NotificationsController: Updating notifications state at %s' , this . storageKey )
177179
178180 // Clean out anything in 'dismissed' that doesn't exist anymore.
179181 const notifications = new Set (
@@ -239,7 +241,7 @@ function registerDismissCommand() {
239241 await NotificationsController . instance . dismissNotification ( notification . id )
240242 } )
241243 } else {
242- getLogger ( 'notifications' ) . error ( `${ name } : Cannot dismiss notification: item is not a vscode.TreeItem` )
244+ logger . error ( `${ name } : Cannot dismiss notification: item is not a vscode.TreeItem` )
243245 }
244246 } )
245247 )
@@ -277,17 +279,23 @@ export class RemoteFetcher implements NotificationFetcher {
277279 const fetcher = new HttpResourceFetcher ( endpoint , {
278280 showUrl : true ,
279281 } )
280- getLogger ( 'notifications' ) . verbose (
281- 'Attempting to fetch notifications for category: %s at endpoint: %s' ,
282- category ,
283- endpoint
282+ logger . verbose ( 'Attempting to fetch notifications for category: %s at endpoint: %s' , category , endpoint )
283+
284+ return withRetries (
285+ async ( ) => {
286+ try {
287+ return await fetcher . getNewETagContent ( versionTag )
288+ } catch ( err ) {
289+ logger . error ( 'Failed to fetch at endpoint: %s, err: %s' , endpoint , err )
290+ throw err
291+ }
292+ } ,
293+ {
294+ maxRetries : RemoteFetcher . retryNumber ,
295+ delay : RemoteFetcher . retryIntervalMs ,
296+ // No exponential backoff - necessary?
297+ }
284298 )
285-
286- return withRetries ( async ( ) => await fetcher . getNewETagContent ( versionTag ) , {
287- maxRetries : RemoteFetcher . retryNumber ,
288- delay : RemoteFetcher . retryIntervalMs ,
289- // No exponential backoff - necessary?
290- } )
291299 }
292300}
293301
@@ -309,11 +317,7 @@ export class LocalFetcher implements NotificationFetcher {
309317
310318 async fetch ( category : NotificationType , versionTag ?: string ) : Promise < ResourceResponse > {
311319 const uri = category === 'startUp' ? this . startUpLocalPath : this . emergencyLocalPath
312- getLogger ( 'notifications' ) . verbose (
313- 'Attempting to fetch notifications locally for category: %s at path: %s' ,
314- category ,
315- uri
316- )
320+ logger . verbose ( 'Attempting to fetch notifications locally for category: %s at path: %s' , category , uri )
317321
318322 return {
319323 content : await new FileResourceFetcher ( globals . context . asAbsolutePath ( uri ) ) . get ( ) ,
0 commit comments