in src/WebJobs.Script/Workers/Rpc/WebHostRpcWorkerChannelManager.cs [175:245]
private bool UsePlaceholderChannel(IRpcWorkerChannel channel)
{
string workerRuntime = channel?.WorkerConfig?.Description?.Language;
if (string.IsNullOrEmpty(workerRuntime))
{
return false;
}
// Restart worker process if custom languageWorkers:[runtime]:arguments are passed in
var workerArguments = _config.GetSection($"{RpcWorkerConstants.LanguageWorkersSectionName}:{workerRuntime}:{WorkerConstants.WorkerDescriptionArguments}").Value;
if (!string.IsNullOrEmpty(workerArguments))
{
return false;
}
if (workerRuntime.Equals(RpcWorkerConstants.DotNetIsolatedLanguageWorkerName, StringComparison.OrdinalIgnoreCase))
{
bool placeholderEnabled = _environment.UsePlaceholderDotNetIsolated();
_logger.LogDebug("UsePlaceholderDotNetIsolated: {placeholderEnabled}", placeholderEnabled);
if (!placeholderEnabled)
{
return false;
}
// We support specialization of dotnet-isolated only on 64bit host process.
if (!_environment.Is64BitProcess)
{
_logger.LogInformation(new EventId(421, ScriptConstants.PlaceholderMissDueToBitnessEventName),
"This app is configured as 32-bit and therefore does not leverage all performance optimizations. See https://aka.ms/azure-functions/dotnet/placeholders for more information.");
return false;
}
// Do not specialize if the placeholder is 6.0 but the site is 7.0 (for example).
var currentWorkerRuntimeVersion = _environment.GetEnvironmentVariable(RpcWorkerConstants.FunctionWorkerRuntimeVersionSettingName);
channel.WorkerProcess.Process.StartInfo.Environment.TryGetValue(RpcWorkerConstants.FunctionWorkerRuntimeVersionSettingName, out string placeholderWorkerRuntimeVersion);
bool versionMatches = string.Equals(currentWorkerRuntimeVersion, placeholderWorkerRuntimeVersion, StringComparison.OrdinalIgnoreCase);
_logger.LogDebug("Placeholder runtime version: '{placeholderWorkerRuntimeVersion}'. Site runtime version: '{currentWorkerRuntimeVersion}'. Match: {versionMatches}",
placeholderWorkerRuntimeVersion, currentWorkerRuntimeVersion, versionMatches);
return versionMatches;
}
// Special case: node, python and PowerShell apps must be read-only to use the placeholder mode channel
// Also cannot use placeholder worker that is targeting ~3 but has backwards compatibility with V2 enabled
// TODO: Remove special casing when resolving https://github.com/Azure/azure-functions-host/issues/4534
if (string.Equals(workerRuntime, RpcWorkerConstants.NodeLanguageWorkerName, StringComparison.OrdinalIgnoreCase)
|| string.Equals(workerRuntime, RpcWorkerConstants.PowerShellLanguageWorkerName, StringComparison.OrdinalIgnoreCase)
|| string.Equals(workerRuntime, RpcWorkerConstants.PythonLanguageWorkerName, StringComparison.OrdinalIgnoreCase))
{
// Use if readonly and not v2 compatible on ~3 extension
var isReadOnlyAndNoCompat = _applicationHostOptions.CurrentValue.IsFileSystemReadOnly && !_environment.IsV2CompatibleOnV3Extension();
if (!isReadOnlyAndNoCompat)
{
_logger.LogDebug("App will not use placeholder channel - ReadOnly: {isReadOnly}. NoCompat: {noCompat}.", _applicationHostOptions.CurrentValue.IsFileSystemReadOnly, !_environment.IsV2CompatibleOnV3Extension());
}
return isReadOnlyAndNoCompat;
}
// If a profile evaluates to true and was not previously loaded, restart worker process
if (!_profileManager.IsCorrectProfileLoaded(workerRuntime))
{
return false;
}
return true;
}