Browse Source

Ensures `isDiscoveringRepositories` covers initialization (for real)

main
Eric Amodio 1 year ago
parent
commit
0dc21c02e2
2 changed files with 35 additions and 23 deletions
  1. +31
    -23
      src/git/gitProviderService.ts
  2. +4
    -0
      src/system/promise.ts

+ 31
- 23
src/git/gitProviderService.ts View File

@ -35,7 +35,15 @@ import { Logger } from '../system/logger';
import { getLogScope, setLogScopeExit } from '../system/logger.scope';
import { getBestPath, getScheme, isAbsolute, maybeUri, normalizePath } from '../system/path';
import type { Deferred } from '../system/promise';
import { asSettled, cancellable, defer, getSettledValue, isPromise, PromiseCancelledError } from '../system/promise';
import {
asSettled,
cancellable,
defer,
getDeferredPromiseIfPending,
getSettledValue,
isPromise,
PromiseCancelledError,
} from '../system/promise';
import { sortCompare } from '../system/string';
import { VisitedPathsTrie } from '../system/trie';
import type {
@ -213,14 +221,14 @@ export class GitProviderService implements Disposable {
Promise<GitRemote<RemoteProvider | RichRemoteProvider>[]>
>();
private readonly _disposable: Disposable;
private _initializingDeferred: Deferred<number> | undefined;
private _initializing: Deferred<number> | undefined;
private readonly _pendingRepositories = new Map<RepoComparisonKey, Promise<Repository | undefined>>();
private readonly _providers = new Map<GitProviderId, GitProvider>();
private readonly _repositories = new Repositories();
private readonly _visitedPaths = new VisitedPathsTrie();
constructor(private readonly container: Container) {
this._initializingDeferred = defer<number>();
this._initializing = defer<number>();
this._disposable = Disposable.from(
container.subscription.onDidChange(this.onSubscriptionChanged, this),
window.onDidChangeWindowState(this.onWindowStateChanged, this),
@ -498,7 +506,7 @@ export class GitProviderService implements Disposable {
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) {
if (this._initializing != null) {
this.onWorkspaceFoldersChanged({ added: workspace.workspaceFolders ?? [], removed: [] });
}
@ -538,14 +546,10 @@ export class GitProviderService implements Disposable {
};
}
private _initializing: boolean = true;
@log({ singleLine: true })
async registrationComplete() {
const scope = getLogScope();
this._initializing = false;
let { workspaceFolders } = workspace;
if (workspaceFolders?.length) {
await this.discoverRepositories(workspaceFolders);
@ -560,6 +564,9 @@ export class GitProviderService implements Disposable {
}, 1000);
}
} else {
this._initializing?.fulfill(this._etag);
this._initializing = undefined;
this.updateContext();
}
@ -606,20 +613,24 @@ export class GitProviderService implements Disposable {
private _discoveredWorkspaceFolders = new Map<WorkspaceFolder, Promise<Repository[]>>();
private _isDiscoveringRepositories: Promise<number> | undefined;
private _discoveringRepositories: Deferred<number> | undefined;
get isDiscoveringRepositories(): Promise<number> | undefined {
return this._isDiscoveringRepositories;
return (
getDeferredPromiseIfPending(this._discoveringRepositories) ??
getDeferredPromiseIfPending(this._initializing)
);
}
@log<GitProviderService['discoverRepositories']>({ args: { 0: folders => folders.length } })
async discoverRepositories(folders: readonly WorkspaceFolder[], options?: { force?: boolean }): Promise<void> {
if (this._isDiscoveringRepositories != null) {
await this._isDiscoveringRepositories;
this._isDiscoveringRepositories = undefined;
if (this._discoveringRepositories?.pending) {
await this._discoveringRepositories.promise;
this._discoveringRepositories = undefined;
}
const deferred = this._initializingDeferred ?? defer<number>();
this._isDiscoveringRepositories = deferred.promise;
const deferred = this._initializing ?? defer<number>();
this._discoveringRepositories = deferred;
this._initializing = undefined;
try {
const promises = [];
@ -662,9 +673,6 @@ export class GitProviderService implements Disposable {
} finally {
queueMicrotask(() => {
deferred.fulfill(this._etag);
if (this._initializingDeferred != null) {
this._initializingDeferred = undefined;
}
});
}
}
@ -1032,7 +1040,7 @@ export class GitProviderService implements Disposable {
async setEnabledContext(enabled: boolean): Promise<void> {
let disabled = !enabled;
// If we think we should be disabled during startup, check if we have a saved value from the last time this repo was loaded
if (!enabled && this._initializing) {
if (!enabled && this._initializing != null) {
disabled = !(this.container.storage.getWorkspace('assumeRepositoriesOnStartup') ?? false);
}
@ -1054,7 +1062,7 @@ export class GitProviderService implements Disposable {
await Promise.allSettled(promises);
if (!this._initializing) {
if (this._initializing == null) {
void this.container.storage.storeWorkspace('assumeRepositoriesOnStartup', enabled).catch();
}
}
@ -1070,7 +1078,7 @@ export class GitProviderService implements Disposable {
void this.setEnabledContext(hasRepositories);
// Don't bother trying to set the values if we're still starting up
if (this._initializing) return;
if (this._initializing != null) return;
this.container.telemetry.setGlobalAttributes({
enabled: hasRepositories,
@ -2278,8 +2286,8 @@ export class GitProviderService implements Disposable {
let repository: Repository | undefined;
repository = this.getRepository(uri);
if (repository == null && this._isDiscoveringRepositories != null) {
await this._isDiscoveringRepositories;
if (repository == null && this._discoveringRepositories?.pending) {
await this._discoveringRepositories.promise;
repository = this.getRepository(uri);
}

+ 4
- 0
src/system/promise.ts View File

@ -161,6 +161,10 @@ export function defer(): Deferred {
return deferred;
}
export function getDeferredPromiseIfPending<T>(deferred: Deferred<T> | undefined): Promise<T> | undefined {
return deferred?.pending ? deferred.promise : undefined;
}
export function getSettledValue<T>(promise: PromiseSettledResult<T> | undefined): T | undefined;
export function getSettledValue<T>(
promise: PromiseSettledResult<T> | undefined,

Loading…
Cancel
Save