@@ -12,6 +12,7 @@ import {
1212 errToStr ,
1313} from "./api-helper"
1414import { Storage } from "./storage"
15+ import { getMemoryLogger , MemoryLogger } from "./memoryLogger"
1516
1617export enum WorkspaceQuery {
1718 Mine = "owner:me" ,
@@ -227,41 +228,80 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
227228// agent and registers a watcher that can be disposed to stop the watch and
228229// emits an event when the metadata changes.
229230function monitorMetadata ( agentId : WorkspaceAgent [ "id" ] , restClient : Api ) : AgentWatcher {
231+ const logger = getMemoryLogger ( )
232+ logger . trackResourceCreated ( "AgentMetadataWatcher" , agentId )
233+
230234 // TODO: Is there a better way to grab the url and token?
231235 const url = restClient . getAxiosInstance ( ) . defaults . baseURL
232236 const metadataUrl = new URL ( `${ url } /api/v2/workspaceagents/${ agentId } /watch-metadata` )
237+
238+ logger . info ( `Starting metadata watcher for agent: ${ agentId } at ${ metadataUrl } ` )
239+
233240 const eventSource = new EventSource ( metadataUrl . toString ( ) , {
234241 fetch : createStreamingFetchAdapter ( restClient . getAxiosInstance ( ) ) ,
235242 } )
236243
237244 let disposed = false
245+ let eventCount = 0
238246 const onChange = new vscode . EventEmitter < null > ( )
239247 const watcher : AgentWatcher = {
240248 onChange : onChange . event ,
241249 dispose : ( ) => {
242250 if ( ! disposed ) {
251+ logger . info ( `Disposing metadata watcher for agent: ${ agentId } after ${ eventCount } events` )
243252 eventSource . close ( )
253+ onChange . dispose ( )
244254 disposed = true
255+ logger . trackResourceDisposed ( "AgentMetadataWatcher" , agentId )
245256 }
246257 } ,
247258 }
248259
260+ eventSource . addEventListener ( "open" , ( ) => {
261+ logger . info ( `Metadata EventSource connection opened for agent: ${ agentId } ` )
262+ } )
263+
249264 eventSource . addEventListener ( "data" , ( event ) => {
265+ eventCount ++
266+
267+ // Log periodic updates
268+ if ( eventCount % 50 === 0 ) {
269+ logger . info ( `Received ${ eventCount } metadata events for agent: ${ agentId } ` )
270+ logger . logMemoryUsage ( "AGENT_METADATA" )
271+ }
272+
250273 try {
251274 const dataEvent = JSON . parse ( event . data )
252275 const metadata = AgentMetadataEventSchemaArray . parse ( dataEvent )
253276
254277 // Overwrite metadata if it changed.
255278 if ( JSON . stringify ( watcher . metadata ) !== JSON . stringify ( metadata ) ) {
279+ if ( eventCount === 1 ) {
280+ logger . debug ( `Initial metadata received for agent: ${ agentId } ` )
281+ }
282+
256283 watcher . metadata = metadata
257284 onChange . fire ( null )
258285 }
259286 } catch ( error ) {
287+ logger . error ( `Error processing metadata for agent: ${ agentId } ` , error )
260288 watcher . error = error
261289 onChange . fire ( null )
262290 }
263291 } )
264292
293+ eventSource . addEventListener ( "error" , ( error ) => {
294+ logger . error ( `Metadata EventSource error for agent: ${ agentId } ` , error )
295+
296+ // If connection closes permanently, clean up resources
297+ if ( ( error as any ) . readyState === EventSource . CLOSED ) {
298+ logger . info ( `Metadata EventSource connection closed for agent: ${ agentId } ` )
299+ if ( ! disposed ) {
300+ watcher . dispose ( )
301+ }
302+ }
303+ } )
304+
265305 return watcher
266306}
267307
0 commit comments