From ae2ceaec43faadf6057f08fe2a64e5234cd2f880 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Tue, 14 Dec 2021 01:54:30 -0500 Subject: [PATCH] Adds etags for view updates --- src/git/gitProviderService.ts | 29 +++++++++++++++++++------ src/git/models/repository.ts | 4 ++++ src/views/nodes/fileHistoryNode.ts | 4 ++-- src/views/nodes/fileHistoryTrackerNode.ts | 4 ++++ src/views/nodes/lineHistoryNode.ts | 4 ++-- src/views/nodes/lineHistoryTrackerNode.ts | 4 ++++ src/views/nodes/repositoriesNode.ts | 4 ++-- src/views/nodes/repositoryNode.ts | 10 ++------- src/views/nodes/viewNode.ts | 36 +++++++++++++++++++++++-------- src/views/viewBase.ts | 2 +- 10 files changed, 70 insertions(+), 31 deletions(-) diff --git a/src/git/gitProviderService.ts b/src/git/gitProviderService.ts index c1c81e4..07e1cec 100644 --- a/src/git/gitProviderService.ts +++ b/src/git/gitProviderService.ts @@ -102,11 +102,21 @@ export class GitProviderService implements Disposable { get onDidChangeProviders(): Event { return this._onDidChangeProviders.event; } + private fireProvidersChanged(added?: GitProvider[], removed?: GitProvider[]) { + this._etag = Date.now(); + + this._onDidChangeProviders.fire({ added: added ?? [], removed: removed ?? [] }); + } private _onDidChangeRepositories = new EventEmitter(); get onDidChangeRepositories(): Event { return this._onDidChangeRepositories.event; } + private fireRepositoriesChanged(added?: Repository[], removed?: Repository[]) { + this._etag = Date.now(); + + this._onDidChangeRepositories.fire({ added: added ?? [], removed: removed ?? [] }); + } private readonly _onDidChangeRepository = new EventEmitter(); get onDidChangeRepository(): Event { @@ -147,6 +157,11 @@ export class GitProviderService implements Disposable { this._repositories.clear(); } + private _etag: number = 0; + get etag(): number { + return this._etag; + } + private onConfigurationChanged(e?: ConfigurationChangeEvent) { if ( configuration.changed(e, 'defaultDateFormat') || @@ -202,7 +217,7 @@ export class GitProviderService implements Disposable { // Defer the event trigger enough to let everything unwind queueMicrotask(() => { - this._onDidChangeRepositories.fire({ added: [], removed: removed }); + this.fireRepositoriesChanged([], removed); removed.forEach(r => r.dispose()); }); } @@ -296,14 +311,14 @@ export class GitProviderService implements Disposable { void this.updateContext(); // Send a notification that the repositories changed - queueMicrotask(() => this._onDidChangeRepositories.fire({ added: [], removed: [e.repository] })); + queueMicrotask(() => this.fireRepositoriesChanged([], [e.repository])); } this._onDidChangeRepository.fire(e); }), ); - this._onDidChangeProviders.fire({ added: [provider], removed: [] }); + this.fireProvidersChanged([provider]); // Don't kick off the discovery if we're still initializing (we'll do it at the end for all "known" providers) if (!this._initializing) { @@ -329,12 +344,12 @@ export class GitProviderService implements Disposable { if (removed.length) { // Defer the event trigger enough to let everything unwind queueMicrotask(() => { - this._onDidChangeRepositories.fire({ added: [], removed: removed }); + this.fireRepositoriesChanged([], removed); removed.forEach(r => r.dispose()); }); } - this._onDidChangeProviders.fire({ added: [], removed: [provider] }); + this.fireProvidersChanged([], [provider]); }, }; } @@ -402,7 +417,7 @@ export class GitProviderService implements Disposable { if (added.length === 0) return; // Defer the event trigger enough to let everything unwind - queueMicrotask(() => this._onDidChangeRepositories.fire({ added: added, removed: [] })); + queueMicrotask(() => this.fireRepositoriesChanged(added)); } private async discoverRepositoriesCore(folder: WorkspaceFolder): Promise { @@ -1413,7 +1428,7 @@ export class GitProviderService implements Disposable { void this.updateContext(); // Send a notification that the repositories changed - queueMicrotask(() => this._onDidChangeRepositories.fire({ added: [repo!], removed: [] })); + queueMicrotask(() => this.fireRepositoriesChanged([repo!])); return rp; } diff --git a/src/git/models/repository.ts b/src/git/models/repository.ts index e9588be..0706201 100644 --- a/src/git/models/repository.ts +++ b/src/git/models/repository.ts @@ -309,6 +309,10 @@ export class Repository implements Disposable { return this._supportsChangeEvents; } + get etag(): number { + return this._updatedAt; + } + private _updatedAt: number = 0; get updatedAt(): number { return this._updatedAt; diff --git a/src/views/nodes/fileHistoryNode.ts b/src/views/nodes/fileHistoryNode.ts index 7477370..dd98bdd 100644 --- a/src/views/nodes/fileHistoryNode.ts +++ b/src/views/nodes/fileHistoryNode.ts @@ -185,8 +185,8 @@ export class FileHistoryNode extends SubscribeableViewNode impl return subscription; } - protected override get requiresResetOnVisible(): boolean { - return true; + protected override etag(): number { + return Date.now(); } private onRepositoryChanged(e: RepositoryChangeEvent) { diff --git a/src/views/nodes/fileHistoryTrackerNode.ts b/src/views/nodes/fileHistoryTrackerNode.ts index b1da69e..8846fbe 100644 --- a/src/views/nodes/fileHistoryTrackerNode.ts +++ b/src/views/nodes/fileHistoryTrackerNode.ts @@ -217,6 +217,10 @@ export class FileHistoryTrackerNode extends SubscribeableViewNode({ args: { 0: e => diff --git a/src/views/nodes/repositoriesNode.ts b/src/views/nodes/repositoriesNode.ts index 55ca848..b182394 100644 --- a/src/views/nodes/repositoriesNode.ts +++ b/src/views/nodes/repositoriesNode.ts @@ -109,8 +109,8 @@ export class RepositoriesNode extends SubscribeableViewNode { return Disposable.from(...subscriptions); } - protected override get requiresResetOnVisible(): boolean { - return true; + protected override etag(): number { + return this.view.container.git.etag; } @debug({ args: false }) diff --git a/src/views/nodes/repositoryNode.ts b/src/views/nodes/repositoryNode.ts index be47bee..f902684 100644 --- a/src/views/nodes/repositoryNode.ts +++ b/src/views/nodes/repositoryNode.ts @@ -352,12 +352,10 @@ export class RepositoryNode extends SubscribeableViewNode { return Disposable.from(...disposables); } - protected override get requiresResetOnVisible(): boolean { - return this._repoUpdatedAt !== this.repo.updatedAt; + protected override etag(): number { + return this.repo.etag; } - private _repoUpdatedAt: number = this.repo.updatedAt; - @debug({ args: { 0: e => @@ -368,8 +366,6 @@ export class RepositoryNode extends SubscribeableViewNode { }, }) private async onFileSystemChanged(_e: RepositoryFileSystemChangeEvent) { - this._repoUpdatedAt = this.repo.updatedAt; - this._status = this.repo.getStatus(); if (this._children !== undefined) { @@ -399,8 +395,6 @@ export class RepositoryNode extends SubscribeableViewNode { @debug({ args: { 0: e => e.toString() } }) private onRepositoryChanged(e: RepositoryChangeEvent) { - this._repoUpdatedAt = this.repo.updatedAt; - if (e.changed(RepositoryChange.Closed, RepositoryChangeComparisonMode.Any)) { this.dispose(); diff --git a/src/views/nodes/viewNode.ts b/src/views/nodes/viewNode.ts index c5c6174..5e326dd 100644 --- a/src/views/nodes/viewNode.ts +++ b/src/views/nodes/viewNode.ts @@ -229,6 +229,9 @@ export abstract class SubscribeableViewNode extends V override async triggerChange(reset: boolean = false, force: boolean = false): Promise { if (!this.loaded) return; + if (reset && !this.view.visible) { + this._pendingReset = reset; + } await super.triggerChange(reset, force); } @@ -247,14 +250,29 @@ export abstract class SubscribeableViewNode extends V } } - protected get requiresResetOnVisible(): boolean { - return false; + private _etag: number | undefined; + protected abstract etag(): number; + + private _pendingReset: boolean = false; + private get requiresResetOnVisible(): boolean { + let reset = this._pendingReset; + this._pendingReset = false; + + const etag = this.etag(); + if (etag !== this._etag) { + this._etag = etag; + reset = true; + } + + return reset; } protected abstract subscribe(): Disposable | undefined | Promise; @debug() protected async unsubscribe(): Promise { + this._etag = this.etag(); + if (this.subscription != null) { const subscriptionPromise = this.subscription; this.subscription = undefined; @@ -308,7 +326,7 @@ export abstract class SubscribeableViewNode extends V if (this.subscription != null) return; this.subscription = Promise.resolve(this.subscribe()); - await this.subscription; + void (await this.subscription); } @gate() @@ -483,18 +501,14 @@ export abstract class RepositoryFolderNode< return this.repo.onDidChange(this.onRepositoryChanged, this); } - protected override get requiresResetOnVisible(): boolean { - return this._repoUpdatedAt !== this.repo.updatedAt; + protected override etag(): number { + return this.repo.etag; } - private _repoUpdatedAt: number = this.repo.updatedAt; - protected abstract changed(e: RepositoryChangeEvent): boolean; @debug({ args: { 0: e => e.toString() } }) private onRepositoryChanged(e: RepositoryChangeEvent) { - this._repoUpdatedAt = this.repo.updatedAt; - if (e.changed(RepositoryChange.Closed, RepositoryChangeComparisonMode.Any)) { this.dispose(); void this.parent?.triggerChange(true); @@ -544,6 +558,10 @@ export abstract class RepositoriesSubscribeableNode< } } + protected override etag(): number { + return this.view.container.git.etag; + } + @debug() protected subscribe(): Disposable | Promise { return this.view.container.git.onDidChangeRepositories(this.onRepositoriesChanged, this); diff --git a/src/views/viewBase.ts b/src/views/viewBase.ts index 7abf04f..d571f61 100644 --- a/src/views/viewBase.ts +++ b/src/views/viewBase.ts @@ -302,7 +302,7 @@ export abstract class ViewBase< } get visible(): boolean { - return this.tree != null ? this.tree.visible : false; + return this.tree?.visible ?? false; } async findNode(