@@ -4,16 +4,18 @@ import {
44 WorkspaceAgent ,
55 WorkspaceApp ,
66} from "coder/site/src/api/typesGenerated" ;
7- import { EventSource } from "eventsource" ;
87import * as path from "path" ;
98import * as vscode from "vscode" ;
10- import { createStreamingFetchAdapter } from "./api" ;
9+ import {
10+ AgentMetadataWatcher ,
11+ createAgentMetadataWatcher ,
12+ formatEventLabel ,
13+ formatMetadataError ,
14+ } from "./agentMetadataHelper" ;
1115import {
1216 AgentMetadataEvent ,
13- AgentMetadataEventSchemaArray ,
1417 extractAllAgents ,
1518 extractAgents ,
16- errToStr ,
1719} from "./api-helper" ;
1820import { Storage } from "./storage" ;
1921
@@ -22,13 +24,6 @@ export enum WorkspaceQuery {
2224 All = "" ,
2325}
2426
25- type AgentWatcher = {
26- onChange : vscode . EventEmitter < null > [ "event" ] ;
27- dispose : ( ) => void ;
28- metadata ?: AgentMetadataEvent [ ] ;
29- error ?: unknown ;
30- } ;
31-
3227/**
3328 * Polls workspaces using the provided REST client and renders them in a tree.
3429 *
@@ -42,7 +37,8 @@ export class WorkspaceProvider
4237{
4338 // Undefined if we have never fetched workspaces before.
4439 private workspaces : WorkspaceTreeItem [ ] | undefined ;
45- private agentWatchers : Record < WorkspaceAgent [ "id" ] , AgentWatcher > = { } ;
40+ private agentWatchers : Record < WorkspaceAgent [ "id" ] , AgentMetadataWatcher > =
41+ { } ;
4642 private timeout : NodeJS . Timeout | undefined ;
4743 private fetching = false ;
4844 private visible = false ;
@@ -139,7 +135,7 @@ export class WorkspaceProvider
139135 return this . agentWatchers [ agent . id ] ;
140136 }
141137 // Otherwise create a new watcher.
142- const watcher = monitorMetadata ( agent . id , restClient ) ;
138+ const watcher = createAgentMetadataWatcher ( agent . id , restClient ) ;
143139 watcher . onChange ( ( ) => this . refresh ( ) ) ;
144140 this . agentWatchers [ agent . id ] = watcher ;
145141 return watcher ;
@@ -313,53 +309,6 @@ export class WorkspaceProvider
313309 }
314310}
315311
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-
363312/**
364313 * A tree item that represents a collapsible section with child items
365314 */
@@ -375,20 +324,14 @@ class SectionTreeItem extends vscode.TreeItem {
375324
376325class ErrorTreeItem extends vscode . TreeItem {
377326 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 ) ;
382328 this . contextValue = "coderAgentMetadata" ;
383329 }
384330}
385331
386332class AgentMetadataTreeItem extends vscode . TreeItem {
387333 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 ) ;
392335
393336 super ( label , vscode . TreeItemCollapsibleState . None ) ;
394337 const collected_at = new Date (
0 commit comments