internal void AddProvider()

in src/WebJobs.Script/Workers/Rpc/Configuration/RpcWorkerConfigFactory.cs [117:212]


        internal void AddProvider(string workerDir)
        {
            using (_metricsLogger.LatencyEvent(string.Format(MetricEventNames.AddProvider, workerDir)))
            {
                try
                {
                    // After specialization, load worker config only for the specified runtime unless it's a multi-language app.
                    if (!string.IsNullOrWhiteSpace(_workerRuntime) && !_environment.IsPlaceholderModeEnabled() && !_environment.IsMultiLanguageRuntimeEnvironment())
                    {
                        string workerRuntime = Path.GetFileName(workerDir);
                        // Only skip worker directories that don't match the current runtime.
                        // Do not skip non-worker directories like the function app payload directory
                        if (!workerRuntime.Equals(_workerRuntime, StringComparison.OrdinalIgnoreCase) && workerDir.StartsWith(WorkersDirPath))
                        {
                            return;
                        }
                    }

                    string workerConfigPath = Path.Combine(workerDir, RpcWorkerConstants.WorkerConfigFileName);

                    if (!File.Exists(workerConfigPath))
                    {
                        _logger.LogDebug("Did not find worker config file at: {workerConfigPath}", workerConfigPath);
                        return;
                    }

                    _logger.LogDebug("Found worker config: {workerConfigPath}", workerConfigPath);

                    var workerConfig = GetWorkerConfigJsonElement(workerConfigPath);
                    var workerDescriptionElement = workerConfig.GetProperty(WorkerConstants.WorkerDescription);
                    var workerDescription = workerDescriptionElement.Deserialize<RpcWorkerDescription>(_jsonSerializerOptions);
                    workerDescription.WorkerDirectory = workerDir;

                    // Read the profiles from worker description and load the profile for which the conditions match
                    if (workerConfig.TryGetProperty(WorkerConstants.WorkerDescriptionProfiles, out var profiles))
                    {
                        List<WorkerDescriptionProfile> workerDescriptionProfiles = ReadWorkerDescriptionProfiles(profiles);
                        if (workerDescriptionProfiles.Count > 0)
                        {
                            _profileManager.SetWorkerDescriptionProfiles(workerDescriptionProfiles, workerDescription.Language);
                            _profileManager.LoadWorkerDescriptionFromProfiles(workerDescription, out workerDescription);
                        }
                    }

                    // Check if any app settings are provided for that language
                    var languageSection = _config.GetSection($"{RpcWorkerConstants.LanguageWorkersSectionName}:{workerDescription.Language}");
                    workerDescription.Arguments ??= new List<string>();
                    GetWorkerDescriptionFromAppSettings(workerDescription, languageSection);
                    AddArgumentsFromAppSettings(workerDescription, languageSection);

                    // Validate workerDescription
                    workerDescription.ApplyDefaultsAndValidate(Directory.GetCurrentDirectory(), _logger);

                    if (workerDescription.IsDisabled == true)
                    {
                        _logger.LogInformation("Skipping WorkerConfig for stack: {language} since it is disabled.", workerDescription.Language);
                        return;
                    }

                    if (ShouldAddWorkerConfig(workerDescription.Language))
                    {
                        workerDescription.FormatWorkerPathIfNeeded(_systemRuntimeInformation, _environment, _logger);
                        workerDescription.FormatWorkingDirectoryIfNeeded();
                        workerDescription.FormatArgumentsIfNeeded(_logger);
                        workerDescription.ThrowIfFileNotExists(workerDescription.DefaultWorkerPath, nameof(workerDescription.DefaultWorkerPath));
                        workerDescription.ExpandEnvironmentVariables();

                        WorkerProcessCountOptions workerProcessCount = GetWorkerProcessCount(workerConfig);

                        var arguments = new WorkerProcessArguments()
                        {
                            ExecutablePath = workerDescription.DefaultExecutablePath,
                            WorkerPath = workerDescription.DefaultWorkerPath
                        };

                        arguments.ExecutableArguments.AddRange(workerDescription.Arguments);

                        var rpcWorkerConfig = new RpcWorkerConfig()
                        {
                            Description = workerDescription,
                            Arguments = arguments,
                            CountOptions = workerProcessCount,
                        };

                        _workerDescriptionDictionary[workerDescription.Language] = rpcWorkerConfig;
                        ReadLanguageWorkerFile(arguments.WorkerPath);

                        _logger.LogDebug("Added WorkerConfig for language: {language}", workerDescription.Language);
                    }
                }
                catch (Exception ex) when (!ex.IsFatal())
                {
                    _logger.LogError(ex, "Failed to initialize worker provider for: {workerDir}", workerDir);
                }
            }
        }