Skip to content

Commit

Permalink
fetch detected tasks twice on clicking "Run Tasks"
Browse files Browse the repository at this point in the history
- detected tasks are fetched N+1 times when users click "Run Tasks" from
the menu, where N is the number of customized detected tasks in the
tasks.json.

- fixes #7496

Signed-off-by: Liang Huang <lhuang4@ualberta.ca>
  • Loading branch information
elaihau committed Apr 9, 2020
1 parent 750d846 commit 5d5d6b5
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 33 deletions.
96 changes: 64 additions & 32 deletions packages/task/src/browser/provided-task-configurations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,43 +62,26 @@ export class ProvidedTaskConfigurations {
* In case that more than one customization is found, return the one that has the biggest number of matched properties.
*
* @param customization the task customization
* @param rootFolderPath the root folder that the detected task comes from
* @return the detected task for the given task customization. If the task customization is not found, `undefined` is returned.
*/
async getTaskToCustomize(customization: TaskCustomization, rootFolderPath: string): Promise<TaskConfiguration | undefined> {
const definition = this.taskDefinitionRegistry.getDefinition(customization);
if (!definition) {
return undefined;
}

const matchedTasks: TaskConfiguration[] = [];
let highest = -1;
const tasks = await this.getTasks();
for (const task of tasks) { // find detected tasks that match the `definition`
let score = 0;
if (!definition.properties.required.every(requiredProp => customization[requiredProp] !== undefined)) {
continue;
}
score += definition.properties.required.length; // number of required properties
const requiredProps = new Set(definition.properties.required);
// number of optional properties
score += definition.properties.all.filter(p => !requiredProps.has(p) && customization[p] !== undefined).length;
if (score >= highest) {
if (score > highest) {
highest = score;
matchedTasks.length = 0;
}
matchedTasks.push(task);
}
}
return this.findMatchedTask(tasks, customization, rootFolderPath);
}

// find the task that matches the `customization`.
// The scenario where more than one match is found should not happen unless users manually enter multiple customizations for one type of task
// If this does happen, return the first match
const rootFolderUri = new URI(rootFolderPath).toString();
const matchedTask = matchedTasks.filter(t =>
rootFolderUri === t._scope && definition.properties.all.every(p => t[p] === customization[p])
)[0];
return matchedTask;
/**
* Finds the detected task from the cache for the given task customization.
* The detected task is considered as a "match" to the task customization if it has all the `required` properties.
* In case that more than one customization is found, return the one that has the biggest number of matched properties.
*
* @param customization the task customization
* @param rootFolderPath the root folder that the detected task comes from
* @return the detected task for the given task customization. If the task customization is not found, `undefined` is returned.
*/
getCachedTaskToCustomize(customization: TaskCustomization, rootFolderPath: string): TaskConfiguration | undefined {
const tasks = this.getCachedTasks();
return this.findMatchedTask(tasks, customization, rootFolderPath);
}

protected getCachedTask(source: string, taskLabel: string, scope?: string): TaskConfiguration | undefined {
Expand All @@ -111,6 +94,18 @@ export class ProvidedTaskConfigurations {
}
}

protected getCachedTasks(): TaskConfiguration[] {
const tasks: TaskConfiguration[] = [];
for (const taskLabelMap of this.tasksMap.values()) {
for (const taskScopeMap of taskLabelMap.values()) {
for (const task of taskScopeMap.values()) {
tasks.push(task);
}
}
}
return tasks;
}

protected cacheTasks(tasks: TaskConfiguration[]): void {
for (const task of tasks) {
const label = task.label;
Expand All @@ -134,4 +129,41 @@ export class ProvidedTaskConfigurations {
}
}
}

// find tasks that matches the `customization` from `tasks`.
private findMatchedTask(tasks: TaskConfiguration[], customization: TaskCustomization, rootFolderPath: string): TaskConfiguration | undefined {
const definition = this.taskDefinitionRegistry.getDefinition(customization);
if (definition) {
const matchedTasks: TaskConfiguration[] = [];
let highest = -1;
for (const task of tasks) { // find detected tasks that match the `definition`
let score = 0;
if (!definition.properties.required.every(requiredProp => customization[requiredProp] !== undefined)) {
continue;
}
score += definition.properties.required.length; // number of required properties
const requiredProps = new Set(definition.properties.required);
// number of optional properties
score += definition.properties.all.filter(p => !requiredProps.has(p) && customization[p] !== undefined).length;
if (score >= highest) {
if (score > highest) {
highest = score;
matchedTasks.length = 0;
}
matchedTasks.push(task);
}
}

if (matchedTasks.length > 0) {
// find the task that matches the `customization`.
// The scenario where more than one match is found should not happen unless users manually enter multiple customizations for one type of task
// If this does happen, return the first match
const rootFolderUri = new URI(rootFolderPath).toString();
const matchedTask = matchedTasks.filter(t =>
rootFolderUri === t._scope && definition.properties.all.every(p => t[p] === customization[p])
)[0];
return matchedTask;
}
}
}
}
6 changes: 5 additions & 1 deletion packages/task/src/browser/task-configurations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,13 @@ export class TaskConfigurations implements Disposable {
async getTasks(): Promise<TaskConfiguration[]> {
const configuredTasks = Array.from(this.tasksMap.values()).reduce((acc, labelConfigMap) => acc.concat(Array.from(labelConfigMap.values())), [] as TaskConfiguration[]);
const detectedTasksAsConfigured: TaskConfiguration[] = [];
let fetchTasksFromProviders = true;
for (const [rootFolder, customizations] of Array.from(this.taskCustomizationMap.entries())) {
for (const cus of customizations) {
const detected = await this.providedTaskConfigurations.getTaskToCustomize(cus, rootFolder);
const detected = fetchTasksFromProviders
? await this.providedTaskConfigurations.getTaskToCustomize(cus, rootFolder)
: this.providedTaskConfigurations.getCachedTaskToCustomize(cus, rootFolder);
fetchTasksFromProviders = false;
if (detected) {
detectedTasksAsConfigured.push({ ...detected, ...cus });
}
Expand Down

0 comments on commit 5d5d6b5

Please sign in to comment.