private bool UsePlaceholderChannel()

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;
        }