private void AddMetadataFromCustomProviders()

in src/WebJobs.Script/Host/FunctionMetadataManager.cs [228:297]


        private void AddMetadataFromCustomProviders(IEnumerable<IFunctionProvider> functionProviders, List<FunctionMetadata> functionMetadataList)
        {
            _logger.ReadingFunctionMetadataFromProvider(MetadataProviderName);

            var functionProviderTasks = new List<Task<ImmutableArray<FunctionMetadata>>>();
            var metadataProviderTimeout = _scriptOptions.Value.MetadataProviderTimeout;

            foreach (var functionProvider in functionProviders)
            {
                var getFunctionMetadataFromProviderTask = functionProvider.GetFunctionMetadataAsync();
                var delayTask = Task.Delay(metadataProviderTimeout);

                var completedTask = Task.WhenAny(getFunctionMetadataFromProviderTask, delayTask).ContinueWith(t =>
                {
                    if (t.Result == getFunctionMetadataFromProviderTask)
                    {
                        return getFunctionMetadataFromProviderTask.Result;
                    }

                    // Timeout case.
                    throw new TimeoutException($"Timeout occurred while retrieving metadata from provider '{functionProvider.GetType().FullName}'. The operation exceeded the configured timeout of {metadataProviderTimeout.TotalSeconds} seconds.");
                });

                functionProviderTasks.Add(completedTask);
            }

            var providerFunctionMetadataResults = Task.WhenAll(functionProviderTasks).GetAwaiter().GetResult();
            var totalFunctionsCount = providerFunctionMetadataResults.Where(metadataArray => !metadataArray.IsDefaultOrEmpty).Sum(metadataArray => metadataArray.Length);

            // This is used to make sure no duplicates are registered
            var distinctFunctionNames = new HashSet<string>(functionMetadataList.Select(m => m.Name));

            _logger.FunctionsReturnedByProvider(totalFunctionsCount, MetadataProviderName);

            foreach (var metadataArray in providerFunctionMetadataResults)
            {
                if (!metadataArray.IsDefaultOrEmpty)
                {
                    foreach (var metadata in metadataArray)
                    {
                        if (distinctFunctionNames.Contains(metadata.Name))
                        {
                            throw new InvalidOperationException($"Found duplicate {nameof(FunctionMetadata)} with the name {metadata.Name}");
                        }

                        // If not explicitly set, consider the function codeless.
                        if (!metadata.IsCodelessSet())
                        {
                            metadata.SetIsCodeless(true);
                        }

                        distinctFunctionNames.Add(metadata.Name);
                        functionMetadataList.Add(metadata);
                    }
                }
            }

            foreach (var functionProvider in functionProviders)
            {
                if (functionProvider.FunctionErrors == null)
                {
                    continue;
                }

                foreach (var errorKvp in functionProvider.FunctionErrors)
                {
                    _functionErrors[errorKvp.Key] = errorKvp.Value.ToList();
                }
            }
        }