@@ -13,7 +13,7 @@ export enum WorkspaceQuery {
13
13
14
14
export class WorkspaceProvider implements vscode . TreeDataProvider < vscode . TreeItem > {
15
15
private workspaces : WorkspaceTreeItem [ ] = [ ]
16
- private agentMetadata : Record < WorkspaceAgent [ "id" ] , AgentMetadataEvent [ ] > = { }
16
+ private agentWatchers : Record < WorkspaceAgent [ "id" ] , { dispose : ( ) => void , metadata ?: AgentMetadataEvent [ ] } > = { }
17
17
18
18
constructor ( private readonly getWorkspacesQuery : WorkspaceQuery , private readonly storage : Storage ) {
19
19
this . fetchAndRefresh ( )
@@ -22,6 +22,7 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
22
22
// fetchAndRefrehsh fetches new workspaces then re-renders the entire tree.
23
23
async fetchAndRefresh ( ) {
24
24
const workspacesTreeItem : WorkspaceTreeItem [ ] = [ ]
25
+ Object . values ( this . agentWatchers ) . forEach ( ( watcher ) => watcher . dispose ( ) )
25
26
// If the URL is set then we are logged in.
26
27
if ( this . storage . getURL ( ) ) {
27
28
const resp = await getWorkspaces ( { q : this . getWorkspacesQuery } )
@@ -62,7 +63,7 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
62
63
)
63
64
return Promise . resolve ( agentTreeItems )
64
65
} else if ( element instanceof AgentTreeItem ) {
65
- const savedMetadata = this . agentMetadata [ element . agent . id ] || [ ]
66
+ const savedMetadata = this . agentWatchers [ element . agent . id ] ?. metadata || [ ]
66
67
return Promise . resolve ( savedMetadata . map ( ( metadata ) => new AgentMetadataTreeItem ( metadata ) ) )
67
68
}
68
69
@@ -71,6 +72,8 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
71
72
return Promise . resolve ( this . workspaces )
72
73
}
73
74
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.
74
77
async monitorMetadata ( agentId : WorkspaceAgent [ "id" ] ) : Promise < void > {
75
78
const agentMetadataURL = new URL ( `${ this . storage . getURL ( ) } /api/v2/workspaceagents/${ agentId } /watch-metadata` )
76
79
const agentMetadataEventSource = new EventSource ( agentMetadataURL . toString ( ) , {
@@ -79,22 +82,29 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
79
82
} ,
80
83
} )
81
84
85
+ this . agentWatchers [ agentId ] = {
86
+ dispose : ( ) => {
87
+ delete ( this . agentWatchers [ agentId ] )
88
+ agentMetadataEventSource . close ( )
89
+ } ,
90
+ }
91
+
82
92
agentMetadataEventSource . addEventListener ( "data" , ( event ) => {
83
93
try {
84
94
const dataEvent = JSON . parse ( event . data )
85
95
const agentMetadata = AgentMetadataEventSchemaArray . parse ( dataEvent )
86
96
87
97
if ( agentMetadata . length === 0 ) {
88
- agentMetadataEventSource . close ( )
98
+ this . agentWatchers [ agentId ] . dispose ( )
89
99
}
90
100
91
- const savedMetadata = this . agentMetadata [ agentId ]
101
+ const savedMetadata = this . agentWatchers [ agentId ] . metadata
92
102
if ( JSON . stringify ( savedMetadata ) !== JSON . stringify ( agentMetadata ) ) {
93
- this . agentMetadata [ agentId ] = agentMetadata // overwrite existing metadata
103
+ this . agentWatchers [ agentId ] . metadata = agentMetadata // overwrite existing metadata
94
104
this . refresh ( )
95
105
}
96
106
} catch ( error ) {
97
- agentMetadataEventSource . close ( )
107
+ this . agentWatchers [ agentId ] . dispose ( )
98
108
}
99
109
} )
100
110
}
0 commit comments