@@ -4,16 +4,18 @@ import {
4
4
WorkspaceAgent ,
5
5
WorkspaceApp ,
6
6
} from "coder/site/src/api/typesGenerated" ;
7
- import { EventSource } from "eventsource" ;
8
7
import * as path from "path" ;
9
8
import * as vscode from "vscode" ;
10
- import { createStreamingFetchAdapter } from "./api" ;
9
+ import {
10
+ AgentMetadataWatcher ,
11
+ createAgentMetadataWatcher ,
12
+ formatEventLabel ,
13
+ formatMetadataError ,
14
+ } from "./agentMetadataHelper" ;
11
15
import {
12
16
AgentMetadataEvent ,
13
- AgentMetadataEventSchemaArray ,
14
17
extractAllAgents ,
15
18
extractAgents ,
16
- errToStr ,
17
19
} from "./api-helper" ;
18
20
import { Storage } from "./storage" ;
19
21
@@ -22,13 +24,6 @@ export enum WorkspaceQuery {
22
24
All = "" ,
23
25
}
24
26
25
- type AgentWatcher = {
26
- onChange : vscode . EventEmitter < null > [ "event" ] ;
27
- dispose : ( ) => void ;
28
- metadata ?: AgentMetadataEvent [ ] ;
29
- error ?: unknown ;
30
- } ;
31
-
32
27
/**
33
28
* Polls workspaces using the provided REST client and renders them in a tree.
34
29
*
@@ -42,7 +37,8 @@ export class WorkspaceProvider
42
37
{
43
38
// Undefined if we have never fetched workspaces before.
44
39
private workspaces : WorkspaceTreeItem [ ] | undefined ;
45
- private agentWatchers : Record < WorkspaceAgent [ "id" ] , AgentWatcher > = { } ;
40
+ private agentWatchers : Record < WorkspaceAgent [ "id" ] , AgentMetadataWatcher > =
41
+ { } ;
46
42
private timeout : NodeJS . Timeout | undefined ;
47
43
private fetching = false ;
48
44
private visible = false ;
@@ -139,7 +135,7 @@ export class WorkspaceProvider
139
135
return this . agentWatchers [ agent . id ] ;
140
136
}
141
137
// Otherwise create a new watcher.
142
- const watcher = monitorMetadata ( agent . id , restClient ) ;
138
+ const watcher = createAgentMetadataWatcher ( agent . id , restClient ) ;
143
139
watcher . onChange ( ( ) => this . refresh ( ) ) ;
144
140
this . agentWatchers [ agent . id ] = watcher ;
145
141
return watcher ;
@@ -313,53 +309,6 @@ export class WorkspaceProvider
313
309
}
314
310
}
315
311
316
- // monitorMetadata opens an SSE endpoint to monitor metadata on the specified
317
- // agent and registers a watcher that can be disposed to stop the watch and
318
- // emits an event when the metadata changes.
319
- function monitorMetadata (
320
- agentId : WorkspaceAgent [ "id" ] ,
321
- restClient : Api ,
322
- ) : AgentWatcher {
323
- // TODO: Is there a better way to grab the url and token?
324
- const url = restClient . getAxiosInstance ( ) . defaults . baseURL ;
325
- const metadataUrl = new URL (
326
- `${ url } /api/v2/workspaceagents/${ agentId } /watch-metadata` ,
327
- ) ;
328
- const eventSource = new EventSource ( metadataUrl . toString ( ) , {
329
- fetch : createStreamingFetchAdapter ( restClient . getAxiosInstance ( ) ) ,
330
- } ) ;
331
-
332
- let disposed = false ;
333
- const onChange = new vscode . EventEmitter < null > ( ) ;
334
- const watcher : AgentWatcher = {
335
- onChange : onChange . event ,
336
- dispose : ( ) => {
337
- if ( ! disposed ) {
338
- eventSource . close ( ) ;
339
- disposed = true ;
340
- }
341
- } ,
342
- } ;
343
-
344
- eventSource . addEventListener ( "data" , ( event ) => {
345
- try {
346
- const dataEvent = JSON . parse ( event . data ) ;
347
- const metadata = AgentMetadataEventSchemaArray . parse ( dataEvent ) ;
348
-
349
- // Overwrite metadata if it changed.
350
- if ( JSON . stringify ( watcher . metadata ) !== JSON . stringify ( metadata ) ) {
351
- watcher . metadata = metadata ;
352
- onChange . fire ( null ) ;
353
- }
354
- } catch ( error ) {
355
- watcher . error = error ;
356
- onChange . fire ( null ) ;
357
- }
358
- } ) ;
359
-
360
- return watcher ;
361
- }
362
-
363
312
/**
364
313
* A tree item that represents a collapsible section with child items
365
314
*/
@@ -375,20 +324,14 @@ class SectionTreeItem extends vscode.TreeItem {
375
324
376
325
class ErrorTreeItem extends vscode . TreeItem {
377
326
constructor ( error : unknown ) {
378
- super (
379
- "Failed to query metadata: " + errToStr ( error , "no error provided" ) ,
380
- vscode . TreeItemCollapsibleState . None ,
381
- ) ;
327
+ super ( formatMetadataError ( error ) , vscode . TreeItemCollapsibleState . None ) ;
382
328
this . contextValue = "coderAgentMetadata" ;
383
329
}
384
330
}
385
331
386
332
class AgentMetadataTreeItem extends vscode . TreeItem {
387
333
constructor ( metadataEvent : AgentMetadataEvent ) {
388
- const label =
389
- metadataEvent . description . display_name . trim ( ) +
390
- ": " +
391
- metadataEvent . result . value . replace ( / \n / g, "" ) . trim ( ) ;
334
+ const label = formatEventLabel ( metadataEvent ) ;
392
335
393
336
super ( label , vscode . TreeItemCollapsibleState . None ) ;
394
337
const collected_at = new Date (
0 commit comments