Skip to content

Commit

Permalink
cherry pick Use consistent scaler IDs for target-based and scale moni…
Browse files Browse the repository at this point in the history
…tor implemen…
  • Loading branch information
cgillum authored and nytian committed Dec 4, 2024
1 parent 09d5094 commit 45cd292
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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"}";
}

/// <inheritdoc/>
public override bool TryGetScaleMonitor(
string functionId,
Expand All @@ -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);
}
Expand All @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -18,27 +16,20 @@ namespace Microsoft.Azure.WebJobs.Extensions.DurableTask
internal sealed class DurableTaskScaleMonitor : IScaleMonitor<DurableTaskTriggerMetrics>
{
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.
Expand Down
12 changes: 8 additions & 4 deletions test/Common/TestEntities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -340,10 +340,14 @@ public static async Task HttpEntity(

private static async Task<int> 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
Expand Down
2 changes: 1 addition & 1 deletion test/FunctionsV2/DurableTaskListenerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
9 changes: 5 additions & 4 deletions test/FunctionsV2/DurableTaskScaleMonitorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down

0 comments on commit 45cd292

Please sign in to comment.