@@ -12,7 +12,7 @@ import {
1212errToStr ,
1313} from "./api-helper"
1414import { Storage } from "./storage"
15- import { getMemoryLogger , MemoryLogger } from "./memoryLogger"
15+ import { getMemoryLogger } from "./memoryLogger"
1616
1717export enum WorkspaceQuery {
1818Mine = "owner:me" ,
@@ -57,10 +57,21 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
5757// Calling this while already refreshing or not visible is a no-op and will
5858// return immediately.
5959async fetchAndRefresh ( ) {
60- if ( this . fetching || ! this . visible ) {
60+ const logger = getMemoryLogger ( )
61+
62+ if ( this . fetching ) {
63+ logger . debug ( `WorkspaceProvider(${ this . getWorkspacesQuery } ): Already fetching, ignoring refresh request` )
64+ return
65+ }
66+
67+ if ( ! this . visible ) {
68+ logger . debug ( `WorkspaceProvider(${ this . getWorkspacesQuery } ): Not visible, ignoring refresh request` )
6169return
6270}
71+
72+ logger . info ( `WorkspaceProvider(${ this . getWorkspacesQuery } ): Starting workspace fetch` )
6373this . fetching = true
74+ let fetchStart = Date . now ( )
6475
6576// It is possible we called fetchAndRefresh() manually (through the button
6677// for example), in which case we might still have a pending refresh that
@@ -70,12 +81,17 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
7081let hadError = false
7182try {
7283this . workspaces = await this . fetch ( )
84+ logger . info (
85+ `WorkspaceProvider(${ this . getWorkspacesQuery } ): Fetch completed in${ Date . now ( ) - fetchStart } ms, found${ this . workspaces . length } workspaces` ,
86+ )
7387} catch ( error ) {
7488hadError = true
89+ logger . error ( `WorkspaceProvider(${ this . getWorkspacesQuery } ): Fetch failed` , error )
7590this . workspaces = [ ]
7691}
7792
7893this . fetching = false
94+ logger . logMemoryUsage ( "WORKSPACE_PROVIDER_FETCH" )
7995
8096this . refresh ( )
8197
@@ -158,45 +174,83 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
158174 * If we have never fetched workspaces and are visible, fetch immediately.
159175 */
160176setVisibility ( visible :boolean ) {
177+ const logger = getMemoryLogger ( )
178+
179+ if ( this . visible !== visible ) {
180+ logger . info ( `WorkspaceProvider(${ this . getWorkspacesQuery } ): Visibility changed to${ visible } ` )
181+ }
182+
161183this . visible = visible
184+
162185if ( ! visible ) {
163186this . cancelPendingRefresh ( )
164187} else if ( ! this . workspaces ) {
188+ logger . info ( `WorkspaceProvider(${ this . getWorkspacesQuery } ): Initial fetch required` )
165189this . fetchAndRefresh ( )
166190} else {
167191this . maybeScheduleRefresh ( )
168192}
169193}
170194
171195private cancelPendingRefresh ( ) {
196+ const logger = getMemoryLogger ( )
197+
172198if ( this . timeout ) {
199+ logger . debug ( `WorkspaceProvider(${ this . getWorkspacesQuery } ): Canceling pending refresh` )
173200clearTimeout ( this . timeout )
174201this . timeout = undefined
175202}
176203}
177-
178204/**
179205 * Schedule a refresh if one is not already scheduled or underway and a
180206 * timeout length was provided.
181207 */
182208private maybeScheduleRefresh ( ) {
209+ const logger = getMemoryLogger ( )
210+
183211if ( this . timerSeconds && ! this . timeout && ! this . fetching ) {
212+ logger . debug ( `WorkspaceProvider(${ this . getWorkspacesQuery } ): Scheduling refresh in${ this . timerSeconds } seconds` )
213+
184214this . timeout = setTimeout ( ( ) => {
215+ logger . debug ( `WorkspaceProvider(${ this . getWorkspacesQuery } ): Executing scheduled refresh` )
185216this . fetchAndRefresh ( )
186217} , this . timerSeconds * 1000 )
187218}
188219}
189-
190220private _onDidChangeTreeData :vscode . EventEmitter < vscode . TreeItem | undefined | null | void > =
191221new vscode . EventEmitter < vscode . TreeItem | undefined | null | void > ( )
192222readonly onDidChangeTreeData :vscode . Event < vscode . TreeItem | undefined | null | void > =
193223this . _onDidChangeTreeData . event
194224
195225// refresh causes the tree to re-render. It does not fetch fresh workspaces.
196226refresh ( item :vscode . TreeItem | undefined | null | void ) :void {
227+ const logger = getMemoryLogger ( )
228+ logger . debug (
229+ `WorkspaceProvider(${ this . getWorkspacesQuery } ): Refreshing tree view${ item ?" for specific item" :"" } ` ,
230+ )
231+
197232this . _onDidChangeTreeData . fire ( item )
198233}
199234
235+ dispose ( ) :void {
236+ const logger = getMemoryLogger ( )
237+ logger . info ( `WorkspaceProvider(${ this . getWorkspacesQuery } ): Disposing` )
238+
239+ // Cancel any pending refreshes
240+ this . cancelPendingRefresh ( )
241+
242+ // Dispose all watchers
243+ Object . keys ( this . agentWatchers ) . forEach ( ( id ) => {
244+ logger . debug ( `WorkspaceProvider(${ this . getWorkspacesQuery } ): Disposing agent watcher${ id } ` )
245+ this . agentWatchers [ id ] . dispose ( )
246+ } )
247+
248+ this . agentWatchers = { }
249+ this . workspaces = undefined
250+
251+ logger . logMemoryUsage ( "WORKSPACE_PROVIDER_DISPOSE" )
252+ }
253+
200254async getTreeItem ( element :vscode . TreeItem ) :Promise < vscode . TreeItem > {
201255return element
202256}