Skip to content

Commit cb95d39

Browse files
committed
Refresh workspaces when logging in and out
I moved the async call out to make it easier to avoid adding new watches if we log out while fetching workspaces.
1 parent 78ff33c commit cb95d39

File tree

2 files changed

+23
-10
lines changed

2 files changed

+23
-10
lines changed

src/commands.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ export class Commands {
108108
vscode.commands.executeCommand("coder.open")
109109
}
110110
})
111+
vscode.commands.executeCommand("coder.refreshWorkspaces")
111112
} catch (error) {
112113
vscode.window.showErrorMessage("Failed to authenticate with Coder: " + error)
113114
}
@@ -122,6 +123,7 @@ export class Commands {
122123
vscode.commands.executeCommand("coder.login")
123124
}
124125
})
126+
vscode.commands.executeCommand("coder.refreshWorkspaces")
125127
}
126128

127129
public async createWorkspace(): Promise<void> {

src/workspacesProvider.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,25 @@ export enum WorkspaceQuery {
1313

1414
export 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()
2020
}
2121

2222
// fetchAndRefrehsh fetches new workspaces then re-renders the entire tree.
2323
async fetchAndRefresh() {
24+
const token = await this.storage.getSessionToken()
2425
const workspacesTreeItem: WorkspaceTreeItem[] = []
26+
Object.values(this.agentWatchers).forEach((watcher) => watcher.dispose())
2527
// If the URL is set then we are logged in.
2628
if (this.storage.getURL()) {
2729
const resp = await getWorkspaces({ q: this.getWorkspacesQuery })
2830
resp.workspaces.forEach((workspace) => {
2931
const showMetadata = this.getWorkspacesQuery === WorkspaceQuery.Mine
30-
if (showMetadata) {
32+
if (showMetadata && token) {
3133
const agents = extractAgents(workspace)
32-
agents.forEach((agent) => this.monitorMetadata(agent.id)) // monitor metadata for all agents
34+
agents.forEach((agent) => this.monitorMetadata(agent.id, token)) // monitor metadata for all agents
3335
}
3436
const treeItem = new WorkspaceTreeItem(workspace, this.getWorkspacesQuery === WorkspaceQuery.All, showMetadata)
3537
workspacesTreeItem.push(treeItem)
@@ -62,7 +64,7 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
6264
)
6365
return Promise.resolve(agentTreeItems)
6466
} else if (element instanceof AgentTreeItem) {
65-
const savedMetadata = this.agentMetadata[element.agent.id] || []
67+
const savedMetadata = this.agentWatchers[element.agent.id]?.metadata || []
6668
return Promise.resolve(savedMetadata.map((metadata) => new AgentMetadataTreeItem(metadata)))
6769
}
6870

@@ -71,30 +73,39 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
7173
return Promise.resolve(this.workspaces)
7274
}
7375

74-
async monitorMetadata(agentId: WorkspaceAgent["id"]): Promise<void> {
76+
// monitorMetadata opens a web socket to monitor metadata on the specified
77+
// agent and registers a disposer that can be used to stop the watch.
78+
monitorMetadata(agentId: WorkspaceAgent["id"], token: string): void {
7579
const agentMetadataURL = new URL(`${this.storage.getURL()}/api/v2/workspaceagents/${agentId}/watch-metadata`)
7680
const agentMetadataEventSource = new EventSource(agentMetadataURL.toString(), {
7781
headers: {
78-
"Coder-Session-Token": await this.storage.getSessionToken(),
82+
"Coder-Session-Token": token,
7983
},
8084
})
8185

86+
this.agentWatchers[agentId] = {
87+
dispose: () => {
88+
delete this.agentWatchers[agentId]
89+
agentMetadataEventSource.close()
90+
},
91+
}
92+
8293
agentMetadataEventSource.addEventListener("data", (event) => {
8394
try {
8495
const dataEvent = JSON.parse(event.data)
8596
const agentMetadata = AgentMetadataEventSchemaArray.parse(dataEvent)
8697

8798
if (agentMetadata.length === 0) {
88-
agentMetadataEventSource.close()
99+
this.agentWatchers[agentId].dispose()
89100
}
90101

91-
const savedMetadata = this.agentMetadata[agentId]
102+
const savedMetadata = this.agentWatchers[agentId].metadata
92103
if (JSON.stringify(savedMetadata) !== JSON.stringify(agentMetadata)) {
93-
this.agentMetadata[agentId] = agentMetadata // overwrite existing metadata
104+
this.agentWatchers[agentId].metadata = agentMetadata // overwrite existing metadata
94105
this.refresh()
95106
}
96107
} catch (error) {
97-
agentMetadataEventSource.close()
108+
this.agentWatchers[agentId].dispose()
98109
}
99110
})
100111
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy