Skip to content

Commit fe185ba

Browse files
committed
Refactor function running task map
1 parent 92c3402 commit fe185ba

File tree

6 files changed

+60
-52
lines changed

6 files changed

+60
-52
lines changed

src/commands/pickFuncProcess.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import * as vscode from 'vscode';
1010
import { hostStartTaskName, ProjectLanguage } from '../constants';
1111
import { preDebugValidate, type IPreDebugValidateResult } from '../debug/validatePreDebug';
1212
import { ext } from '../extensionVariables';
13-
import { buildPathToWorkspaceFolderMap, get, getFuncPortFromTaskOrProject, isFuncHostTask, runningFuncTaskMap, stopFuncTaskIfRunning, type IRunningFuncTask } from '../funcCoreTools/funcHostTask';
13+
import { buildPathToWorkspaceFolderMap, getFuncPortFromTaskOrProject, isFuncHostTask, runningFuncTaskMap, stopFuncTaskIfRunning, type IRunningFuncTask } from '../funcCoreTools/funcHostTask';
1414
import { localize } from '../localize';
1515
import { delay } from '../utils/delay';
1616
import { requestUtils } from '../utils/requestUtils';
@@ -56,7 +56,8 @@ export async function startFuncProcessFromApi(
5656

5757
const funcTask = new vscode.Task({ type: `func ${buildPath}` },
5858
workspaceFolder,
59-
hostStartTaskName, `func`,
59+
hostStartTaskName,
60+
`func`,
6061
new vscode.ShellExecution(funcHostStartCmd, {
6162
cwd: buildPath,
6263
env
@@ -147,7 +148,7 @@ async function startFuncTask(context: IActionContext, workspaceFolder: vscode.Wo
147148
throw taskError;
148149
}
149150

150-
const taskInfo: IRunningFuncTask | undefined = get(runningFuncTaskMap, workspaceFolder, buildPath);
151+
const taskInfo: IRunningFuncTask | undefined = runningFuncTaskMap.get(workspaceFolder, buildPath);
151152
if (taskInfo) {
152153
for (const scheme of ['http', 'https']) {
153154
const statusRequest: AzExtRequestPrepareOptions = { url: `${scheme}://localhost:${funcPort}/admin/host/status`, method: 'GET' };

src/commands/startFunctionApp.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ export async function startFunctionApp(context: IActionContext, node?: SlotTreeI
1414
node = await pickFunctionApp(context);
1515
}
1616

17-
1817
const client: SiteClient = await node.site.createClient(context);
1918
await node.runWithTemporaryDescription(
2019
context,

src/funcCoreTools/funcHostTask.ts

Lines changed: 51 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,51 @@ namespace DotnetDebugDebugConfiguration {
2828
}
2929
}
3030

31-
export const runningFuncTaskMap: Map<vscode.WorkspaceFolder | vscode.TaskScope, IRunningFuncTask[]> = new Map<vscode.WorkspaceFolder | vscode.TaskScope, IRunningFuncTask[]>();
31+
class RunningFunctionTaskMap {
32+
private _map: Map<vscode.WorkspaceFolder | vscode.TaskScope, IRunningFuncTask[]> = new Map<vscode.WorkspaceFolder | vscode.TaskScope, IRunningFuncTask[]>();
33+
34+
public set(key: vscode.WorkspaceFolder | vscode.TaskScope, value: IRunningFuncTask): void {
35+
const values = this._map.get(key) || [];
36+
values.push(value)
37+
this._map.set(key, values);
38+
}
39+
40+
public get(key: vscode.WorkspaceFolder | vscode.TaskScope, buildPath?: string): IRunningFuncTask | undefined {
41+
const values = this._map.get(key) || [];
42+
return values.find(t => {
43+
const taskExecution = t.taskExecution.task.execution as vscode.ShellExecution;
44+
// the cwd will include ${workspaceFolder} from our tasks.json so we need to replace it with the actual path
45+
const taskDirectory = taskExecution.options?.cwd?.replace('${workspaceFolder}', (t.taskExecution.task?.scope as vscode.WorkspaceFolder).uri?.path)
46+
buildPath = buildPath?.replace('${workspaceFolder}', (t.taskExecution.task?.scope as vscode.WorkspaceFolder).uri?.path)
47+
return taskDirectory && buildPath && normalizePath(taskDirectory) === normalizePath(buildPath);
48+
});
49+
}
50+
51+
public getAll(key: vscode.WorkspaceFolder | vscode.TaskScope): (IRunningFuncTask | undefined)[] {
52+
return this._map.get(key) || [];
53+
}
54+
55+
public has(key: vscode.WorkspaceFolder | vscode.TaskScope, buildPath?: string): boolean {
56+
return !!this.get(key, buildPath);
57+
}
58+
59+
public delete(key: vscode.WorkspaceFolder | vscode.TaskScope, buildPath?: string): void {
60+
const value = this.get(key, buildPath)
61+
const values = this._map.get(key) || [];
62+
63+
if (value) {
64+
// remove the individual entry from the array
65+
values.splice(values.indexOf(value), 1);
66+
this._map.set(key, values);
67+
}
68+
69+
if (values?.length === 0) {
70+
this._map.delete(key);
71+
}
72+
}
73+
}
74+
75+
export const runningFuncTaskMap: RunningFunctionTaskMap = new RunningFunctionTaskMap();
3276

3377
const funcTaskStartedEmitter = new vscode.EventEmitter<vscode.WorkspaceFolder | vscode.TaskScope>();
3478
export const onFuncTaskStarted = funcTaskStartedEmitter.event;
@@ -48,17 +92,16 @@ export function registerFuncHostTaskEvents(): void {
4892
if (e.execution.task.scope !== undefined && isFuncHostTask(e.execution.task)) {
4993
const portNumber = await getFuncPortFromTaskOrProject(context, e.execution.task, e.execution.task.scope);
5094
const runningFuncTask = { processId: e.processId, taskExecution: e.execution, portNumber };
51-
set(runningFuncTaskMap, e.execution.task.scope, runningFuncTask);
95+
runningFuncTaskMap.set(e.execution.task.scope, runningFuncTask);
5296
funcTaskStartedEmitter.fire(e.execution.task.scope);
5397
}
5498
});
5599

56100
registerEvent('azureFunctions.onDidEndTask', vscode.tasks.onDidEndTaskProcess, (context: IActionContext, e: vscode.TaskProcessEndEvent) => {
57101
context.errorHandling.suppressDisplay = true;
58102
context.telemetry.suppressIfSuccessful = true;
59-
// e.execution.task.execution.options.cwd will be the build path
60103
if (e.execution.task.scope !== undefined && isFuncHostTask(e.execution.task)) {
61-
remove(runningFuncTaskMap, e.execution.task.scope, (e.execution.task.execution as vscode.ShellExecution).options?.cwd);
104+
runningFuncTaskMap.delete(e.execution.task.scope, (e.execution.task.execution as vscode.ShellExecution).options?.cwd);
62105
}
63106
});
64107

@@ -91,9 +134,10 @@ export function registerFuncHostTaskEvents(): void {
91134
export function stopFuncTaskIfRunning(workspaceFolder: vscode.WorkspaceFolder | vscode.TaskScope, buildPath?: string, killAll?: boolean, terminate?: boolean): void {
92135
let runningFuncTask: (IRunningFuncTask | undefined)[] | undefined;
93136
if (killAll) {
94-
runningFuncTask = runningFuncTaskMap.get(workspaceFolder);
137+
// get all is needed here
138+
runningFuncTask = runningFuncTaskMap.getAll(workspaceFolder);
95139
} else {
96-
runningFuncTask = [get(runningFuncTaskMap, workspaceFolder, buildPath)];
140+
runningFuncTask = [runningFuncTaskMap.get(workspaceFolder, buildPath)];
97141
}
98142

99143
if (runningFuncTask !== undefined) {
@@ -110,7 +154,7 @@ export function stopFuncTaskIfRunning(workspaceFolder: vscode.WorkspaceFolder |
110154
}
111155
}
112156
if (buildPath) {
113-
remove(runningFuncTaskMap, workspaceFolder, buildPath);
157+
runningFuncTaskMap.delete(workspaceFolder, buildPath);
114158
}
115159
}
116160

@@ -154,42 +198,6 @@ export async function getFuncPortFromTaskOrProject(context: IActionContext, func
154198
return defaultFuncPort;
155199
}
156200

157-
function set(map: Map<vscode.WorkspaceFolder | vscode.TaskScope, IRunningFuncTask[]>, key: vscode.WorkspaceFolder | vscode.TaskScope, value: IRunningFuncTask): void {
158-
const values = map.get(key) || [];
159-
values.push(value)
160-
map.set(key, values);
161-
}
162-
163-
export function get(map: Map<vscode.WorkspaceFolder | vscode.TaskScope, IRunningFuncTask[]>, key: vscode.WorkspaceFolder | vscode.TaskScope, buildPath?: string): IRunningFuncTask | undefined {
164-
const values = map.get(key) || [];
165-
return values.find(t => {
166-
const taskExecution = t.taskExecution.task.execution as vscode.ShellExecution;
167-
// the cwd will include ${workspaceFolder} from our tasks.json so we need to replace it with the actual path
168-
const taskDirectory = taskExecution.options?.cwd?.replace('${workspaceFolder}', (t.taskExecution.task?.scope as vscode.WorkspaceFolder).uri?.path)
169-
buildPath = buildPath?.replace('${workspaceFolder}', (t.taskExecution.task?.scope as vscode.WorkspaceFolder).uri?.path)
170-
return taskDirectory && buildPath && normalizePath(taskDirectory) === normalizePath(buildPath);
171-
});
172-
}
173-
174-
export function has(map: Map<vscode.WorkspaceFolder | vscode.TaskScope, IRunningFuncTask[]>, key: vscode.WorkspaceFolder | vscode.TaskScope, buildPath?: string): boolean {
175-
return !!get(map, key, buildPath);
176-
}
177-
178-
function remove(map: Map<vscode.WorkspaceFolder | vscode.TaskScope, IRunningFuncTask[]>, key: vscode.WorkspaceFolder | vscode.TaskScope, buildPath?: string): void {
179-
const value = get(map, key, buildPath)
180-
const values = map.get(key) || [];
181-
182-
if (value) {
183-
// remove the individual entry from the array
184-
values.splice(values.indexOf(value), 1);
185-
map.set(key, values);
186-
}
187-
188-
if (values?.length === 0) {
189-
map.delete(key);
190-
}
191-
}
192-
193201
function normalizePath(fsPath: string): string {
194202
return vscode.Uri.parse(path.normalize(fsPath).replace(/^(\/|\\)+|(\/|\\)+$/g, '')).fsPath;
195203
}

src/workspace/LocalProject.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { type FuncVersion } from "../FuncVersion";
99
import { hostFileName, localSettingsFileName } from "../constants";
1010
import { parseHostJson, type IParsedHostJson } from "../funcConfig/host";
1111
import { MismatchBehavior, getLocalSettingsJson, setLocalAppSetting, type ILocalSettingsJson } from "../funcConfig/local.settings";
12-
import { get, getFuncPortFromTaskOrProject, isFuncHostTask, runningFuncTaskMap } from "../funcCoreTools/funcHostTask";
12+
import { getFuncPortFromTaskOrProject, isFuncHostTask, runningFuncTaskMap } from "../funcCoreTools/funcHostTask";
1313
import { type ApplicationSettings, type FuncHostRequest } from "../tree/IProjectTreeItem";
1414
import { ProjectSource } from "../tree/projectContextValues";
1515
import { requestUtils } from "../utils/requestUtils";
@@ -42,7 +42,7 @@ export class LocalProject implements LocalProjectInternal {
4242
}
4343

4444
public async getHostRequest(context: IActionContext): Promise<FuncHostRequest> {
45-
let port = get(runningFuncTaskMap, this.options.folder)?.portNumber;
45+
let port = runningFuncTaskMap.get(this.options.folder)?.portNumber;
4646
if (!port) {
4747
const funcTask: Task | undefined = (await tasks.fetchTasks()).find(t => t.scope === this.options.folder && isFuncHostTask(t));
4848
port = await getFuncPortFromTaskOrProject(context, funcTask, this.options.effectiveProjectPath);

src/workspace/listLocalFunctions.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { type AzExtPipelineResponse } from '@microsoft/vscode-azext-azureutils';
88
import { AzExtFsExtra, callWithTelemetryAndErrorHandling, nonNullProp, parseError, type IActionContext } from "@microsoft/vscode-azext-utils";
99
import { functionJsonFileName } from "../constants";
1010
import { ParsedFunctionJson } from "../funcConfig/function";
11-
import { has, runningFuncTaskMap } from "../funcCoreTools/funcHostTask";
11+
import { runningFuncTaskMap } from "../funcCoreTools/funcHostTask";
1212
import { ProjectNotRunningError, getFunctionFolders } from "../tree/localProject/LocalFunctionsTreeItem";
1313
import { nonNullValue } from "../utils/nonNull";
1414
import { isNodeV4Plus, isPythonV2Plus } from "../utils/programmingModelUtils";
@@ -76,7 +76,7 @@ function getHostStartTimeoutMS(): number {
7676
* Some projects (e.g. .NET Isolated and PyStein (i.e. Python model >=2)) don't have typical "function.json" files, so we'll have to ping localhost to get functions (only available if the project is running)
7777
*/
7878
async function getFunctionsForHostedProject(context: IActionContext, project: LocalProjectInternal): Promise<ILocalFunction[]> {
79-
if (has(runningFuncTaskMap, project.options.folder, project.options.effectiveProjectPath)) {
79+
if (runningFuncTaskMap.has(project.options.folder, project.options.effectiveProjectPath)) {
8080
const hostRequest = await project.getHostRequest(context);
8181
const timeout = getHostStartTimeoutMS();
8282
const startTime = Date.now();

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"compilerOptions": {
33
"module": "commonjs",
4-
"target": "es2021",
4+
"target": "es2018",
55
"outDir": "out",
66
"lib": [
77
"es6"

0 commit comments

Comments
 (0)