diff --git a/NuGet.Config b/NuGet.Config index 09c86f97c..f4ea0c9a7 100644 --- a/NuGet.Config +++ b/NuGet.Config @@ -9,5 +9,6 @@ + diff --git a/eng/build/Packages.props b/eng/build/Packages.props index ad31fec61..f205dcbf4 100644 --- a/eng/build/Packages.props +++ b/eng/build/Packages.props @@ -20,7 +20,7 @@ - + @@ -32,11 +32,11 @@ - + - - + + diff --git a/release_notes.md b/release_notes.md index 45dd435ce..aeb6ce347 100644 --- a/release_notes.md +++ b/release_notes.md @@ -1,13 +1,14 @@ -# Azure Functions CLI 4.4.0 +# Azure Functions CLI 4.5.0 #### Host Version -- Host Version: 4.1043.200 -- In-Proc Host Version: 4.41.100 (4.841.100, 4.641.100) +- Host Version: 4.1044.400 +- In-Proc Host Version: 4.44.100 (4.844.100, 4.644.100) #### Changes - Add updated Durable .NET templates (#4692) - Adding the MCP Tool Trigger Templates for the Node/Typescript (#4651) - Set `AzureWebJobsStorage` to use the storage emulator by default on all platforms (#4685) +- Set `FUNCTIONS_WORKER_RUNTIME` to custom if the `EnableMcpCustomHandlerPreview` feature flag is set (#4703) - Update .NET isolated templates package to 4.0.5331 (#4712) diff --git a/src/Cli/func/Actions/HostActions/StartHostAction.cs b/src/Cli/func/Actions/HostActions/StartHostAction.cs index d5fd75928..b138c5836 100644 --- a/src/Cli/func/Actions/HostActions/StartHostAction.cs +++ b/src/Cli/func/Actions/HostActions/StartHostAction.cs @@ -464,7 +464,7 @@ public override async Task RunAsync() if (hostService.State is not ScriptHostState.Stopping && hostService.State is not ScriptHostState.Stopped) { - await hostService.DelayUntilHostReady(); + await hostService.DelayUntilHostReadyAsync(); var scriptHost = hostService.Services.GetRequiredService(); var httpOptions = hostService.Services.GetRequiredService>(); diff --git a/src/Cli/func/Common/Utilities.cs b/src/Cli/func/Common/Utilities.cs index 124d8919b..1b540b729 100644 --- a/src/Cli/func/Common/Utilities.cs +++ b/src/Cli/func/Common/Utilities.cs @@ -297,9 +297,10 @@ internal static bool IsSystemLogCategory(string category) internal static IConfigurationRoot BuildHostJsonConfigutation(ScriptApplicationHostOptions hostOptions) { - IConfigurationBuilder builder = new ConfigurationBuilder(); - builder.Add(new HostJsonFileConfigurationSource(hostOptions, SystemEnvironment.Instance, loggerFactory: NullLoggerFactory.Instance, metricsLogger: new MetricsLogger())); - var configuration = builder.Build(); + var builder = new ConfigurationBuilder(); + var hostJsonFileConfigurationOptions = new HostJsonFileConfigurationOptions(hostOptions); + builder.Add(new HostJsonFileConfigurationSource(hostJsonFileConfigurationOptions, loggerFactory: NullLoggerFactory.Instance, metricsLogger: new MetricsLogger())); + IConfigurationRoot configuration = builder.Build(); return configuration; } diff --git a/src/Cli/func/Directory.Version.props b/src/Cli/func/Directory.Version.props index bab5f2326..2fe77b42b 100644 --- a/src/Cli/func/Directory.Version.props +++ b/src/Cli/func/Directory.Version.props @@ -1,7 +1,7 @@ - 4.4.0 + 4.5.0 true diff --git a/src/Cli/func/ExtensionBundle/ExtensionBundleHelper.cs b/src/Cli/func/ExtensionBundle/ExtensionBundleHelper.cs index e66b0cfd8..ba5332af0 100644 --- a/src/Cli/func/ExtensionBundle/ExtensionBundleHelper.cs +++ b/src/Cli/func/ExtensionBundle/ExtensionBundleHelper.cs @@ -39,7 +39,8 @@ public static ExtensionBundleManager GetExtensionBundleManager() } var configOptions = new FunctionsHostingConfigOptions(); - return new ExtensionBundleManager(extensionBundleOption, SystemEnvironment.Instance, NullLoggerFactory.Instance, configOptions); + IHttpClientFactory httpClientFactory = new SimpleHttpClientFactory(); + return new ExtensionBundleManager(extensionBundleOption, SystemEnvironment.Instance, NullLoggerFactory.Instance, configOptions, httpClientFactory); } public static ExtensionBundleContentProvider GetExtensionBundleContentProvider() diff --git a/src/Cli/func/ExtensionBundle/SimpleHttpClientFactory.cs b/src/Cli/func/ExtensionBundle/SimpleHttpClientFactory.cs new file mode 100644 index 000000000..884e6ba1c --- /dev/null +++ b/src/Cli/func/ExtensionBundle/SimpleHttpClientFactory.cs @@ -0,0 +1,40 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using System.Collections.Concurrent; +using System.Net; + +namespace Azure.Functions.Cli.ExtensionBundle +{ + /// + /// Minimal IHttpClientFactory implementation for Core Tools. + /// Reuses a single HttpClient per logical name to avoid socket exhaustion. + /// + internal class SimpleHttpClientFactory : IHttpClientFactory + { + private readonly ConcurrentDictionary _clients = new(); + private static readonly TimeSpan _defaultTimeout = TimeSpan.FromMinutes(1); + + public HttpClient CreateClient(string name) + { + // Name can be ignored for now except for providing isolation if needed later. + return _clients.GetOrAdd(name ?? string.Empty, static _ => + { + var handler = new SocketsHttpHandler + { + AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate, + PooledConnectionIdleTimeout = TimeSpan.FromMinutes(2), + PooledConnectionLifetime = TimeSpan.FromMinutes(10) + }; + + var client = new HttpClient(handler, disposeHandler: true) + { + Timeout = _defaultTimeout + }; + + client.DefaultRequestHeaders.UserAgent.ParseAdd("azure-functions-core-tools-extension-bundle"); + return client; + }); + } + } +}