@@ -13,7 +13,7 @@ export enum WorkspaceQuery {
1313
1414export class WorkspaceProvider implements vscode . TreeDataProvider < vscode . TreeItem > {
1515 private workspaces : WorkspaceTreeItem [ ] = [ ]
16- private agentMetadata : Record < WorkspaceAgent [ "id" ] , AgentMetadataEvent [ ] > = { }
16+ private agentWatchers : Record < WorkspaceAgent [ "id" ] , { dispose : ( ) => void , metadata ?: AgentMetadataEvent [ ] } > = { }
1717
1818 constructor ( private readonly getWorkspacesQuery : WorkspaceQuery , private readonly storage : Storage ) {
1919 this . fetchAndRefresh ( )
@@ -22,6 +22,7 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
2222 // fetchAndRefrehsh fetches new workspaces then re-renders the entire tree.
2323 async fetchAndRefresh ( ) {
2424 const workspacesTreeItem : WorkspaceTreeItem [ ] = [ ]
25+ Object . values ( this . agentWatchers ) . forEach ( ( watcher ) => watcher . dispose ( ) )
2526 // If the URL is set then we are logged in.
2627 if ( this . storage . getURL ( ) ) {
2728 const resp = await getWorkspaces ( { q : this . getWorkspacesQuery } )
@@ -62,7 +63,7 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
6263 )
6364 return Promise . resolve ( agentTreeItems )
6465 } else if ( element instanceof AgentTreeItem ) {
65- const savedMetadata = this . agentMetadata [ element . agent . id ] || [ ]
66+ const savedMetadata = this . agentWatchers [ element . agent . id ] ?. metadata || [ ]
6667 return Promise . resolve ( savedMetadata . map ( ( metadata ) => new AgentMetadataTreeItem ( metadata ) ) )
6768 }
6869
@@ -71,6 +72,8 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
7172 return Promise . resolve ( this . workspaces )
7273 }
7374
75+ // monitorMetadata opens a web socket to monitor metadata on the specified
76+ // agent and registers a disposer that can be used to stop the watch.
7477 async monitorMetadata ( agentId : WorkspaceAgent [ "id" ] ) : Promise < void > {
7578 const agentMetadataURL = new URL ( `${ this . storage . getURL ( ) } /api/v2/workspaceagents/${ agentId } /watch-metadata` )
7679 const agentMetadataEventSource = new EventSource ( agentMetadataURL . toString ( ) , {
@@ -79,22 +82,29 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
7982 } ,
8083 } )
8184
85+ this . agentWatchers [ agentId ] = {
86+ dispose : ( ) => {
87+ delete ( this . agentWatchers [ agentId ] )
88+ agentMetadataEventSource . close ( )
89+ } ,
90+ }
91+
8292 agentMetadataEventSource . addEventListener ( "data" , ( event ) => {
8393 try {
8494 const dataEvent = JSON . parse ( event . data )
8595 const agentMetadata = AgentMetadataEventSchemaArray . parse ( dataEvent )
8696
8797 if ( agentMetadata . length === 0 ) {
88- agentMetadataEventSource . close ( )
98+ this . agentWatchers [ agentId ] . dispose ( )
8999 }
90100
91- const savedMetadata = this . agentMetadata [ agentId ]
101+ const savedMetadata = this . agentWatchers [ agentId ] . metadata
92102 if ( JSON . stringify ( savedMetadata ) !== JSON . stringify ( agentMetadata ) ) {
93- this . agentMetadata [ agentId ] = agentMetadata // overwrite existing metadata
103+ this . agentWatchers [ agentId ] . metadata = agentMetadata // overwrite existing metadata
94104 this . refresh ( )
95105 }
96106 } catch ( error ) {
97- agentMetadataEventSource . close ( )
107+ this . agentWatchers [ agentId ] . dispose ( )
98108 }
99109 } )
100110 }
0 commit comments