Skip to content

Commit 94f3033

Browse files
Update logic to set the function app root for both programming models
1 parent e34b400 commit 94f3033

File tree

3 files changed

+39
-24
lines changed

3 files changed

+39
-24
lines changed

src/FunctionLoader.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,9 @@ internal static void ClearLoadedFunctions()
7272
/// Setup the well known paths about the FunctionApp.
7373
/// This method is called only once during the code start.
7474
/// </summary>
75-
internal static void SetupWellKnownPaths(FunctionLoadRequest request, string managedDependenciesPath)
75+
internal static void SetupWellKnownPaths(string functionAppRootPath, string managedDependenciesPath)
7676
{
77-
// Resolve the FunctionApp root path
78-
FunctionAppRootPath = Path.GetFullPath(Path.Join(request.Metadata.Directory, ".."));
77+
FunctionAppRootPath = functionAppRootPath;
7978

8079
// Resolve module paths
8180
var appLevelModulesPath = Path.Join(FunctionAppRootPath, "Modules");

src/RequestProcessor.cs

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ internal class RequestProcessor
3232
private readonly PowerShellManagerPool _powershellPool;
3333
private DependencyManager _dependencyManager;
3434
private string _pwshVersion;
35+
private string _functionAppRootPath;
3536

3637
// Holds the exception if an issue is encountered while processing the function app dependencies.
3738
private Exception _initTerminatingError;
@@ -135,18 +136,6 @@ internal StreamingMessage ProcessWorkerInitRequest(StreamingMessage request)
135136

136137
response.WorkerInitResponse.WorkerMetadata = GetWorkerMetadata(_pwshVersion);
137138

138-
// Previously, the dependency management would happen just prior to the dependency download in the
139-
// first function load request. Now that we have the FunctionAppDirectory in the WorkerInitRequest,
140-
// we can do the setup of these variables in the function load request. We need these variables initialized
141-
// for the FunctionMetadataRequest, should it be sent.
142-
_dependencyManager = new DependencyManager(request.WorkerInitRequest.FunctionAppDirectory, logger: rpcLogger);
143-
144-
// The profile is invoke during this stage.
145-
// TODO: Initialize the first PowerShell instance, but delay the invocation of the profile.
146-
// The first PowerShell instance will be used to import the PowerShell SDK to generate the function metadata
147-
// Issue: We do not know if Managed Dependencies is enabled until the first function load.
148-
_powershellPool.Initialize(_firstPwshInstance);
149-
150139
rpcLogger.Log(isUserOnlyLog: false, LogLevel.Trace, string.Format(PowerShellWorkerStrings.WorkerInitCompleted, stopwatch.ElapsedMilliseconds));
151140
}
152141
catch (Exception e)
@@ -231,16 +220,39 @@ internal StreamingMessage ProcessFunctionLoadRequest(StreamingMessage request)
231220
{
232221
try
233222
{
223+
_isFunctionAppInitialized = true;
224+
234225
var rpcLogger = new RpcLogger(_msgStream);
235226
rpcLogger.SetContext(request.RequestId, null);
236227

237-
_isFunctionAppInitialized = true;
228+
// _functionAppRootPath is set in ProcessFunctionMetadataRequest for the v2 progamming model.
229+
if (_functionAppRootPath == null)
230+
{
231+
// If _functionAppRootPath is null, this means that this is an app for the v1 programming model.
232+
_functionAppRootPath = request.FunctionLoadRequest.Metadata.Directory;
233+
}
238234

235+
if (string.IsNullOrWhiteSpace(_functionAppRootPath))
236+
{
237+
throw new ArgumentException("Failed to resolve the function app root", nameof(_functionAppRootPath));
238+
}
239+
240+
_dependencyManager = new DependencyManager(_functionAppRootPath, logger: rpcLogger);
239241
var managedDependenciesPath = _dependencyManager.Initialize(request, rpcLogger);
240242

241-
SetupAppRootPathAndModulePath(request.FunctionLoadRequest, managedDependenciesPath);
243+
SetupAppRootPathAndModulePath(_functionAppRootPath, managedDependenciesPath);
244+
245+
// The profile is invoke when the instance is initialized.
246+
// TODO: Initialize the first PowerShell instance but delay the invocation of the profile until the first function load.
247+
// The first PowerShell instance will be used to import the AzureFunctions.PowerShell.SDK to generate the function metadata
248+
// Issue: We do not know if Managed Dependencies is enabled until the first function load.
249+
_powershellPool.Initialize(_firstPwshInstance);
250+
242251
// Start the download asynchronously if needed.
243252
_dependencyManager.StartDependencyInstallationIfNeeded(request, _firstPwshInstance, rpcLogger);
253+
254+
rpcLogger.Log(isUserOnlyLog: false, LogLevel.Trace, string.Format(PowerShellWorkerStrings.FirstFunctionLoadCompleted, stopwatch.ElapsedMilliseconds));
255+
244256
}
245257
catch (Exception e)
246258
{
@@ -387,8 +399,8 @@ private StreamingMessage ProcessFunctionMetadataRequest(StreamingMessage request
387399
var rpcLogger = new RpcLogger(_msgStream);
388400
rpcLogger.SetContext(request.RequestId, null);
389401

390-
//response.FunctionMetadataResponse.FunctionMetadataResults.AddRange(WorkerIndexingHelper.IndexFunctions(request.FunctionsMetadataRequest.FunctionAppDirectory));
391-
response.FunctionMetadataResponse.FunctionMetadataResults.AddRange(WorkerIndexingHelper.IndexFunctions(request.FunctionsMetadataRequest.FunctionAppDirectory, rpcLogger));
402+
_functionAppRootPath = request.FunctionsMetadataRequest.FunctionAppDirectory;
403+
response.FunctionMetadataResponse.FunctionMetadataResults.AddRange(WorkerIndexingHelper.IndexFunctions(_functionAppRootPath, rpcLogger));
392404

393405
return response;
394406
}
@@ -559,9 +571,9 @@ private static void BindOutputFromResult(InvocationResponse response, AzFunction
559571
}
560572
}
561573

562-
private void SetupAppRootPathAndModulePath(FunctionLoadRequest functionLoadRequest, string managedDependenciesPath)
574+
private void SetupAppRootPathAndModulePath(string functionAppRootPath, string managedDependenciesPath)
563575
{
564-
FunctionLoader.SetupWellKnownPaths(functionLoadRequest, managedDependenciesPath);
576+
FunctionLoader.SetupWellKnownPaths(functionAppRootPath, managedDependenciesPath);
565577

566578
if (FunctionLoader.FunctionAppRootPath == null)
567579
{

src/WorkerIndexing/WorkerIndexingHelper.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,13 @@ internal class WorkerIndexingHelper
2626
const string AzureFunctionsPowerShellSDKModuleName = "AzureFunctions.PowerShell.SDK";
2727
private static readonly ErrorRecordFormatter _errorRecordFormatter = new ErrorRecordFormatter();
2828

29-
//internal static IEnumerable<RpcFunctionMetadata> IndexFunctions(string baseDir)
30-
internal static IEnumerable<RpcFunctionMetadata> IndexFunctions(string baseDir, ILogger logger)
29+
internal static IEnumerable<RpcFunctionMetadata> IndexFunctions(string functionAppRootPath, ILogger logger)
3130
{
31+
if (string.IsNullOrWhiteSpace(functionAppRootPath))
32+
{
33+
throw new ArgumentException("Empty function app root path", nameof(functionAppRootPath));
34+
}
35+
3236
List<RpcFunctionMetadata> indexedFunctions = new List<RpcFunctionMetadata>();
3337

3438
// This is not the correct way to deal with getting a runspace for the cmdlet.
@@ -66,7 +70,7 @@ internal static IEnumerable<RpcFunctionMetadata> IndexFunctions(string baseDir,
6670

6771
try
6872
{
69-
_powershell.AddCommand(GetFunctionsMetadataCmdletName).AddArgument(baseDir);
73+
_powershell.AddCommand(GetFunctionsMetadataCmdletName).AddArgument(functionAppRootPath);
7074
results = _powershell.Invoke();
7175
cmdletExecutionHadErrors = _powershell.HadErrors;
7276
}

0 commit comments

Comments
 (0)