Merge pull request #2165 from github/koesie10/simpler-progress-task

Simpler `withProgress` calls
This commit is contained in:
Koen Vlaswinkel
2023-03-14 12:06:59 +01:00
committed by GitHub
4 changed files with 115 additions and 106 deletions

View File

@@ -1,6 +1,6 @@
import {
CancellationToken,
ProgressOptions,
ProgressOptions as VSCodeProgressOptions,
window as Window,
commands,
Disposable,
@@ -42,22 +42,40 @@ export interface ProgressUpdate {
export type ProgressCallback = (p: ProgressUpdate) => void;
// Make certain properties within a type optional
type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
export type ProgressOptions = Optional<VSCodeProgressOptions, "location">;
/**
* A task that reports progress.
*
* @param progress a progress handler function. Call this
* function with a `ProgressUpdate` instance in order to
* denote some progress being achieved on this task.
* @param token a cancellation token
*/
export type ProgressTask<R> = (
progress: ProgressCallback,
token: CancellationToken,
) => Thenable<R>;
/**
* A task that handles command invocations from `commandRunner`
* and includes a progress monitor.
*
*
* Arguments passed to the command handler are passed along,
* untouched to this `ProgressTask` instance.
* untouched to this `ProgressTaskWithArgs` instance.
*
* @param progress a progress handler function. Call this
* function with a `ProgressUpdate` instance in order to
* denote some progress being achieved on this task.
* @param token a cencellation token
* @param token a cancellation token
* @param args arguments passed to this task passed on from
* `commands.registerCommand`.
*/
export type ProgressTask<R> = (
export type ProgressTaskWithArgs<R> = (
progress: ProgressCallback,
token: CancellationToken,
...args: any[]
@@ -90,23 +108,29 @@ type NoProgressTask = (...args: any[]) => Promise<any>;
* request).
*/
export function withProgress<R>(
options: ProgressOptions,
task: ProgressTask<R>,
...args: any[]
{
location = ProgressLocation.Notification,
title,
cancellable,
}: ProgressOptions = {},
): Thenable<R> {
let progressAchieved = 0;
return Window.withProgress(options, (progress, token) => {
return task(
(p) => {
return Window.withProgress(
{
location,
title,
cancellable,
},
(progress, token) => {
return task((p) => {
const { message, step, maxStep } = p;
const increment = (100 * (step - progressAchieved)) / maxStep;
progressAchieved = step;
progress.report({ message, increment });
},
token,
...args,
);
});
}, token);
},
);
}
/**
@@ -177,19 +201,17 @@ export function commandRunner(
*/
export function commandRunnerWithProgress<R>(
commandId: string,
task: ProgressTask<R>,
progressOptions: Partial<ProgressOptions>,
task: ProgressTaskWithArgs<R>,
progressOptions: ProgressOptions,
outputLogger = extLogger,
): Disposable {
return commandRunner(
commandId,
async (...args: any[]) => {
const progressOptionsWithDefaults = {
location: ProgressLocation.Notification,
...progressOptions,
};
return withProgress(progressOptionsWithDefaults, task, ...args);
return withProgress(
(progress, token) => task(progress, token, ...args),
progressOptions,
);
},
outputLogger,
);

View File

@@ -4,7 +4,6 @@ import {
Location,
LocationLink,
Position,
ProgressLocation,
ReferenceContext,
ReferenceProvider,
TextDocument,
@@ -73,11 +72,6 @@ export class TemplateQueryDefinitionProvider implements DefinitionProvider {
private async getDefinitions(uriString: string): Promise<LocationLink[]> {
return withProgress(
{
location: ProgressLocation.Notification,
cancellable: true,
title: "Finding definitions",
},
async (progress, token) => {
return getLocationsForUriString(
this.cli,
@@ -91,6 +85,10 @@ export class TemplateQueryDefinitionProvider implements DefinitionProvider {
(src, _dest) => src === uriString,
);
},
{
cancellable: true,
title: "Finding definitions",
},
);
}
}
@@ -136,11 +134,6 @@ export class TemplateQueryReferenceProvider implements ReferenceProvider {
private async getReferences(uriString: string): Promise<FullLocationLink[]> {
return withProgress(
{
location: ProgressLocation.Notification,
cancellable: true,
title: "Finding references",
},
async (progress, token) => {
return getLocationsForUriString(
this.cli,
@@ -154,6 +147,10 @@ export class TemplateQueryReferenceProvider implements ReferenceProvider {
(src, _dest) => src === uriString,
);
},
{
cancellable: true,
title: "Finding references",
},
);
}
}

View File

@@ -9,7 +9,6 @@ import {
extensions,
languages,
ProgressLocation,
ProgressOptions,
QuickPickItem,
Range,
Uri,
@@ -322,16 +321,15 @@ export async function activate(
await commands.executeCommand("workbench.action.reloadWindow");
}
} else {
const progressOptions: ProgressOptions = {
title: progressTitle,
location: ProgressLocation.Notification,
};
await withProgress(progressOptions, (progress) =>
distributionManager.installExtensionManagedDistributionRelease(
result.updatedRelease,
progress,
),
await withProgress(
(progress) =>
distributionManager.installExtensionManagedDistributionRelease(
result.updatedRelease,
progress,
),
{
title: progressTitle,
},
);
await ctx.globalState.update(shouldUpdateOnNextActivationKey, false);

View File

@@ -794,74 +794,66 @@ export class DatabaseManager extends DisposableObject {
}
public async loadPersistedState(): Promise<void> {
return withProgress(
{
location: vscode.ProgressLocation.Notification,
},
async (progress, token) => {
const currentDatabaseUri =
this.ctx.workspaceState.get<string>(CURRENT_DB);
const databases = this.ctx.workspaceState.get<PersistedDatabaseItem[]>(
DB_LIST,
[],
return withProgress(async (progress, token) => {
const currentDatabaseUri =
this.ctx.workspaceState.get<string>(CURRENT_DB);
const databases = this.ctx.workspaceState.get<PersistedDatabaseItem[]>(
DB_LIST,
[],
);
let step = 0;
progress({
maxStep: databases.length,
message: "Loading persisted databases",
step,
});
try {
void this.logger.log(
`Found ${databases.length} persisted databases: ${databases
.map((db) => db.uri)
.join(", ")}`,
);
let step = 0;
progress({
maxStep: databases.length,
message: "Loading persisted databases",
step,
});
try {
void this.logger.log(
`Found ${databases.length} persisted databases: ${databases
.map((db) => db.uri)
.join(", ")}`,
);
for (const database of databases) {
progress({
maxStep: databases.length,
message: `Loading ${
database.options?.displayName || "databases"
}`,
step: ++step,
});
for (const database of databases) {
progress({
maxStep: databases.length,
message: `Loading ${database.options?.displayName || "databases"}`,
step: ++step,
});
const databaseItem =
await this.createDatabaseItemFromPersistedState(
progress,
token,
database,
);
try {
await databaseItem.refresh();
await this.registerDatabase(progress, token, databaseItem);
if (currentDatabaseUri === database.uri) {
await this.setCurrentDatabaseItem(databaseItem, true);
}
void this.logger.log(
`Loaded database ${databaseItem.name} at URI ${database.uri}.`,
);
} catch (e) {
// When loading from persisted state, leave invalid databases in the list. They will be
// marked as invalid, and cannot be set as the current database.
void this.logger.log(
`Error loading database ${database.uri}: ${e}.`,
);
const databaseItem = await this.createDatabaseItemFromPersistedState(
progress,
token,
database,
);
try {
await databaseItem.refresh();
await this.registerDatabase(progress, token, databaseItem);
if (currentDatabaseUri === database.uri) {
await this.setCurrentDatabaseItem(databaseItem, true);
}
void this.logger.log(
`Loaded database ${databaseItem.name} at URI ${database.uri}.`,
);
} catch (e) {
// When loading from persisted state, leave invalid databases in the list. They will be
// marked as invalid, and cannot be set as the current database.
void this.logger.log(
`Error loading database ${database.uri}: ${e}.`,
);
}
await this.updatePersistedDatabaseList();
} catch (e) {
// database list had an unexpected type - nothing to be done?
void showAndLogExceptionWithTelemetry(
redactableError(
asError(e),
)`Database list loading failed: ${getErrorMessage(e)}`,
);
}
await this.updatePersistedDatabaseList();
} catch (e) {
// database list had an unexpected type - nothing to be done?
void showAndLogExceptionWithTelemetry(
redactableError(
asError(e),
)`Database list loading failed: ${getErrorMessage(e)}`,
);
}
void this.logger.log("Finished loading persisted databases.");
},
);
void this.logger.log("Finished loading persisted databases.");
});
}
public get databaseItems(): readonly DatabaseItem[] {