From 45cd2927f1117d72651f7c4c2059aa8542e1f01b Mon Sep 17 00:00:00 2001 From: Chris Gillum Date: Tue, 3 Dec 2024 12:26:39 -0800 Subject: [PATCH] =?UTF-8?q?cherry=20pick=20Use=20consistent=20scaler=20IDs?= =?UTF-8?q?=20for=20target-based=20and=20scale=20monitor=20implemen?= =?UTF-8?q?=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AzureStorageDurabilityProvider.cs | 27 ++++++++++++++----- .../Listener/DurableTaskScaleMonitor.cs | 13 ++------- test/Common/TestEntities.cs | 12 ++++++--- test/FunctionsV2/DurableTaskListenerTests.cs | 2 +- .../DurableTaskScaleMonitorTests.cs | 9 ++++--- 5 files changed, 37 insertions(+), 26 deletions(-) diff --git a/src/WebJobs.Extensions.DurableTask/AzureStorageDurabilityProvider.cs b/src/WebJobs.Extensions.DurableTask/AzureStorageDurabilityProvider.cs index bfd5d8e4f..895b99872 100644 --- a/src/WebJobs.Extensions.DurableTask/AzureStorageDurabilityProvider.cs +++ b/src/WebJobs.Extensions.DurableTask/AzureStorageDurabilityProvider.cs @@ -243,6 +243,13 @@ internal DurableTaskMetricsProvider GetMetricsProvider( return new DurableTaskMetricsProvider(hubName, logger, performanceMonitor: null, storageAccountClientProvider); } + // Common routine for getting the scaler ID. Note that we MUST use the same ID for both the + // scale monitor and the target scaler. + private static string GetScalerUniqueId(string hubName) + { + return $"DurableTask-AzureStorage:{hubName ?? "default"}"; + } + /// public override bool TryGetScaleMonitor( string functionId, @@ -255,11 +262,17 @@ public override bool TryGetScaleMonitor( { if (this.singletonScaleMonitor == null) { - StorageAccountClientProvider storageAccountClientProvider = this.clientProviderFactory.GetClientProvider(connectionName); - DurableTaskMetricsProvider metricsProvider = this.GetMetricsProvider(hubName, storageAccountClientProvider, this.logger); + DurableTaskMetricsProvider metricsProvider = this.GetMetricsProvider( + hubName, + this.clientProviderFactory.GetClientProvider(connectionName), + this.logger); + + // Scalers in Durable Functions are shared for all functions in the same task hub. + // So instead of using a function ID, we use the task hub name as the basis for the descriptor ID. + string id = GetScalerUniqueId(hubName); this.singletonScaleMonitor = new DurableTaskScaleMonitor( + id, hubName, - storageAccountClientProvider, this.logger, metricsProvider); } @@ -283,12 +296,14 @@ public override bool TryGetTargetScaler( if (this.singletonTargetScaler == null) { // This is only called by the ScaleController, it doesn't run in the Functions Host process. - StorageAccountClientProvider storageAccountClientProvider = this.clientProviderFactory.GetClientProvider(connectionName); - DurableTaskMetricsProvider metricsProvider = this.GetMetricsProvider(hubName, storageAccountClientProvider, this.logger); + DurableTaskMetricsProvider metricsProvider = this.GetMetricsProvider( + hubName, + this.clientProviderFactory.GetClientProvider(connectionName), + this.logger); // Scalers in Durable Functions are shared for all functions in the same task hub. // So instead of using a function ID, we use the task hub name as the basis for the descriptor ID. - string id = $"DurableTask-AzureStorage:{hubName ?? "default"}"; + string id = GetScalerUniqueId(hubName); this.singletonTargetScaler = new DurableTaskTargetScaler(id, metricsProvider, this, this.logger); } diff --git a/src/WebJobs.Extensions.DurableTask/Listener/DurableTaskScaleMonitor.cs b/src/WebJobs.Extensions.DurableTask/Listener/DurableTaskScaleMonitor.cs index ae896ee3c..ce0da320b 100644 --- a/src/WebJobs.Extensions.DurableTask/Listener/DurableTaskScaleMonitor.cs +++ b/src/WebJobs.Extensions.DurableTask/Listener/DurableTaskScaleMonitor.cs @@ -6,8 +6,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Azure; -using DurableTask.AzureStorage; using DurableTask.AzureStorage.Monitoring; using Microsoft.Azure.WebJobs.Host.Scale; using Microsoft.Extensions.Logging; @@ -18,27 +16,20 @@ namespace Microsoft.Azure.WebJobs.Extensions.DurableTask internal sealed class DurableTaskScaleMonitor : IScaleMonitor { private readonly string hubName; - private readonly StorageAccountClientProvider storageAccountClientProvider; private readonly ScaleMonitorDescriptor scaleMonitorDescriptor; private readonly ILogger logger; private readonly DurableTaskMetricsProvider durableTaskMetricsProvider; - private DisconnectedPerformanceMonitor performanceMonitor; - public DurableTaskScaleMonitor( + string id, string hubName, - StorageAccountClientProvider storageAccountClientProvider, ILogger logger, - DurableTaskMetricsProvider durableTaskMetricsProvider, - DisconnectedPerformanceMonitor performanceMonitor = null) + DurableTaskMetricsProvider durableTaskMetricsProvider) { this.hubName = hubName; - this.storageAccountClientProvider = storageAccountClientProvider; this.logger = logger; - this.performanceMonitor = performanceMonitor; this.durableTaskMetricsProvider = durableTaskMetricsProvider; - string id = $"DurableTaskTrigger-{this.hubName}".ToLower(); #if FUNCTIONS_V3_OR_GREATER // Scalers in Durable Functions are shared for all functions in the same task hub. // So instead of using a function ID, we use the task hub name as the basis for the descriptor ID. diff --git a/test/Common/TestEntities.cs b/test/Common/TestEntities.cs index a1ba7e15b..5bf6ecd0a 100644 --- a/test/Common/TestEntities.cs +++ b/test/Common/TestEntities.cs @@ -340,10 +340,14 @@ public static async Task HttpEntity( private static async Task CallHttpAsync(string requestUri) { - using (HttpResponseMessage response = await SharedHttpClient.GetAsync(requestUri)) - { - return (int)response.StatusCode; - } + ////using (HttpResponseMessage response = await SharedHttpClient.GetAsync(requestUri)) + ////{ + //// return (int)response.StatusCode; + ////} + + // Making real calls to HTTP endpoints is not reliable in tests. + await Task.Delay(100); + return 200; } //-------------- an entity that uses custom deserialization diff --git a/test/FunctionsV2/DurableTaskListenerTests.cs b/test/FunctionsV2/DurableTaskListenerTests.cs index 886e5a1b3..e79b51586 100644 --- a/test/FunctionsV2/DurableTaskListenerTests.cs +++ b/test/FunctionsV2/DurableTaskListenerTests.cs @@ -37,7 +37,7 @@ public void GetMonitor_ReturnsExpectedValue() IScaleMonitor scaleMonitor = this.listener.GetMonitor(); Assert.Equal(typeof(DurableTaskScaleMonitor), scaleMonitor.GetType()); - Assert.Equal($"DurableTaskTrigger-DurableTaskHub".ToLower(), scaleMonitor.Descriptor.Id); + Assert.Equal($"DurableTask-AzureStorage:DurableTaskHub", scaleMonitor.Descriptor.Id); IScaleMonitor scaleMonitor2 = this.listener.GetMonitor(); diff --git a/test/FunctionsV2/DurableTaskScaleMonitorTests.cs b/test/FunctionsV2/DurableTaskScaleMonitorTests.cs index 87c988c5b..3ea4f9297 100644 --- a/test/FunctionsV2/DurableTaskScaleMonitorTests.cs +++ b/test/FunctionsV2/DurableTaskScaleMonitorTests.cs @@ -48,19 +48,20 @@ public DurableTaskScaleMonitorTests(ITestOutputHelper output) this.performanceMonitor.Object, this.clientProvider); + string scalerId = $"DurableTask-AzureStorage:{this.hubName}"; + this.scaleMonitor = new DurableTaskScaleMonitor( + scalerId, this.hubName, - this.clientProvider, logger, - metricsProvider, - this.performanceMonitor.Object); + metricsProvider); } [Fact] [Trait("Category", PlatformSpecificHelpers.TestCategory)] public void ScaleMonitorDescriptor_ReturnsExpectedValue() { - Assert.Equal($"DurableTaskTrigger-{this.hubName}".ToLower(), this.scaleMonitor.Descriptor.Id); + Assert.Equal($"DurableTask-AzureStorage:{this.hubName}", this.scaleMonitor.Descriptor.Id); } [Fact]