Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
705526e
Unifying scale logic
alrod Feb 3, 2023
79a0486
Scale API refinements
mathewc Feb 6, 2023
d7bd09e
Adding host options
alrod Feb 10, 2023
49ede7a
Adding hostig config to webjobs sdk
alrod Feb 11, 2023
3e3b1a0
Fix some issues
alrod Feb 14, 2023
8ad30bd
Update to 3.0.37
alrod Feb 15, 2023
c7bf959
Fix VersionSuffix
alrod Feb 16, 2023
476ba91
Scaler API updates
mathewc Feb 16, 2023
c1a8a93
Merge branch 'scaler-apis-mathewc' into scaler-apis
alrod Feb 17, 2023
d6f781d
Fix commnets
alrod Mar 1, 2023
5d77b9a
Remove some APIs
alrod Mar 2, 2023
79d9086
Fix Microsoft.FeatureManagement reference
alrod Mar 2, 2023
e2b08af
AddHostedService for ScaleMonitorService
alrod Mar 3, 2023
3d15a6a
Changing FeatureManagement to IConfiguration
alrod Mar 6, 2023
b59bf70
Fix ScaleManagerTests
alrod Mar 6, 2023
b7479b5
Fix comments
alrod Mar 8, 2023
256602f
Making GetScalersToSample static
alrod Mar 9, 2023
d101ac2
Fix ScaleOptions logging
alrod Mar 9, 2023
8b6936a
Fix typo
alrod Mar 9, 2023
87d1cc2
Fix Vincent comments
alrod Mar 10, 2023
00bf27f
Scaler API updates
mathewc Mar 10, 2023
bd3ebb0
Fix comments
alrod Mar 13, 2023
4467104
Fix comments
alrod Mar 13, 2023
e0c7520
AddOptionsLogging fix
alrod Mar 14, 2023
9f68638
Always create properties in TriggerMetadata
alrod Mar 14, 2023
26ed467
Introducing IScaleStatusProvider
alrod Mar 15, 2023
fcc5aaf
Fix ScaleHostEndToEndTests
alrod Mar 16, 2023
bdf6ac7
Last fixes
alrod Mar 22, 2023
82cd90a
Fix AsyncChainEndToEndTests
alrod Mar 22, 2023
be2550e
Try to fix CI
alrod Mar 22, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions build/common.props
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project>
<PropertyGroup>
<!-- Packages can have independent versions and only increment when released -->
<Version>3.0.36$(VersionSuffix)</Version>
<HostStorageVersion>5.0.0-beta.2$(VersionSuffix)</HostStorageVersion>
<Version>3.0.37$(VersionSuffix)</Version>
<HostStorageVersion>5.0.0$(VersionSuffix)</HostStorageVersion>
<LoggingVersion>4.0.3$(VersionSuffix)</LoggingVersion>

<TargetFramework>netstandard2.0</TargetFramework>
Expand Down
2 changes: 1 addition & 1 deletion sample/SampleHost/SampleHost.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.EventHubs" Version="3.0.6" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.ServiceBus" Version="3.1.1" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="5.0.0-beta.5" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.1.1" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ public static void AddAzureStorageCoreServices(this IServiceCollection services)
services.AddSingleton<IConcurrencyStatusRepository, BlobStorageConcurrencyStatusRepository>();
}

public static void AddAzureStorageScaleServices(this IServiceCollection services)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this meant to ever be called by a customer?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this will be called from ScaleController, see example here:
https://github.com/Azure/azure-webjobs-sdk/blob/scaler-apis/test/Microsoft.Azure.WebJobs.Host.EndToEndTests/Scale/ScaleHostEndToEndTests.cs#L84

Function host is not supposed to call this.

{
services.TryAddEnumerable(ServiceDescriptor.Transient<IConfigureOptions<JobHostInternalStorageOptions>, CoreWebJobsOptionsSetup<JobHostInternalStorageOptions>>());
services.TryAddSingleton<IAzureBlobStorageProvider, AzureStorageProvider>();
services.AddSingleton<IConcurrencyStatusRepository, BlobStorageConcurrencyStatusRepository>();
Comment thread
chiangvincent marked this conversation as resolved.
}

// This is only called if the host didn't already provide an implementation
private static IDistributedLockManager Create(IServiceProvider provider)
{
Expand Down
1 change: 1 addition & 0 deletions src/Microsoft.Azure.WebJobs.Host/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ internal static class Constants
public const string AzureWebsiteInstanceId = "WEBSITE_INSTANCE_ID";
public const string AzureWebsiteContainerName = "CONTAINER_NAME";
public const string DateTimeFormatString = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffK";
public const string HostingConfigSectionName = "HostingConfig";
Comment thread
alrod marked this conversation as resolved.
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Linq;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host.Scale;
using Microsoft.Azure.WebJobs.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.EnvironmentVariables;
Expand Down Expand Up @@ -135,6 +136,26 @@ public static IHostBuilder ConfigureWebJobs(this IHostBuilder builder, Action<Ho
return builder;
}

/// <summary>
/// Configures the specified <see cref="IHostBuilder"/> as a scale manager host. This method is used for internal infrastructure only.
/// </summary>
/// <param name="builder">The <see cref="IHostBuilder"/> to configure.</param>
/// <param name="configure">Configuration action to perform as part of service configuration.</param>
/// <param name="configureScaleOptions">Configuration action for <see cref="ScaleOptions"/>.</param>
/// <returns>The <see cref="IHostBuilder"/>.</returns>
public static IHostBuilder ConfigureWebJobsScale(this IHostBuilder builder,
Action<HostBuilderContext, IWebJobsBuilder> configure,
Action<ScaleOptions> configureScaleOptions)
{
builder.ConfigureServices((context, services) =>
{
IWebJobsBuilder webJobsBuilder = services.AddWebJobsScale(configureScaleOptions);
configure?.Invoke(context, webJobsBuilder);
});

return builder;
}

private static IConfigurationBuilder TryAddDefaultConfigurationSources(this IConfigurationBuilder config)
{
if (!config.Sources.OfType<JsonConfigurationSource>().Any(p => string.Equals(p.Path, "appsettings.json", StringComparison.OrdinalIgnoreCase)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public static class WebJobsServiceCollectionExtensions
{
private const string SingletonConfigSectionName = "Singleton";
private const string ConcurrencyConfigSectionName = "Concurrency";
private const string ScaleConfigSectionName = "Scale";

/// <summary>
/// Adds the WebJobs services to the provided <see cref="IServiceCollection"/>.
Expand Down Expand Up @@ -87,8 +88,9 @@ public static IWebJobsBuilder AddWebJobs(this IServiceCollection services, Actio
services.TryAddSingleton<IFunctionInstanceLogger, FunctionInstanceLogger>();
services.TryAddSingleton<IHostInstanceLogger, NullHostInstanceLogger>();
services.TryAddSingleton<IDistributedLockManager, InMemoryDistributedLockManager>();
services.TryAddSingleton<IScaleMonitorManager, ScaleMonitorManager>();
services.TryAddSingleton<ITargetScalerManager, TargetScalerManager>();

services.AddCommonScaleServices();
services.TryAddSingleton<IScaleMetricsRepository, NullScaleMetricsRepository>();

services.AddSingleton<IPrimaryHostStateProvider, PrimaryHostStateProvider>();
services.AddSingleton<IHostedService, PrimaryHostCoordinator>();
Expand Down Expand Up @@ -116,12 +118,7 @@ public static IWebJobsBuilder AddWebJobs(this IServiceCollection services, Actio
services.AddSingleton(typeof(IWebJobsExtensionConfiguration<>), typeof(WebJobsExtensionConfiguration<>));

// Options logging
services.AddTransient(typeof(OptionsFactory<>));
services.AddTransient(typeof(IOptionsFactory<>), typeof(WebJobsOptionsFactory<>));
services.AddSingleton<IOptionsLoggingSource, OptionsLoggingSource>();
services.AddSingleton<IHostedService, OptionsLoggingService>();
services.AddSingleton<IOptionsFormatter<LoggerFilterOptions>, LoggerFilterOptionsFormatter>();

services.AddOptionsLogging();
// Concurrency management
services.TryAddSingleton<IConcurrencyStatusRepository, NullConcurrencyStatusRepository>();
services.TryAddSingleton<IHostProcessMonitor, DefaultHostProcessMonitor>();
Expand Down Expand Up @@ -159,5 +156,58 @@ public static IWebJobsBuilder AddWebJobs(this IServiceCollection services, Actio

return builder;
}

/// <summary>
/// Adds the WebJobs scale services to the provided <see cref="IServiceCollection"/>.
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
public static IWebJobsBuilder AddWebJobsScale(this IServiceCollection services, Action<ScaleOptions> configure)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}

services.AddCommonScaleServices();
services.TryAddSingleton<IPrimaryHostStateProvider>(new PrimaryHostStateProvider() { IsPrimary = true });

if (configure != null)
{
services.Configure(configure);
}

services.AddOptionsLogging();

var builder = new WebJobsBuilder(services);
return builder;
}

/// <summary>
/// Adds scale services common to both normal WebJobs and ScaleHost scenarios.
/// </summary>
/// <param name="services"></param>
private static void AddCommonScaleServices(this IServiceCollection services)
{
services.AddOptions<ScaleOptions>()
.Configure<IConfiguration>((options, config) =>
{
var section = config.GetWebJobsRootConfiguration().GetSection(ScaleConfigSectionName);
section.Bind(options);
});
services.TryAddSingleton<IScaleMonitorManager, ScaleMonitorManager>();
services.TryAddSingleton<ITargetScalerManager, TargetScalerManager>();
services.TryAddSingleton<IScaleStatusProvider, ScaleManager>();
services.AddHostedService<ScaleMonitorService>();
}

private static void AddOptionsLogging(this IServiceCollection services)
{
services.AddTransient(typeof(OptionsFactory<>));
services.AddTransient(typeof(IOptionsFactory<>), typeof(WebJobsOptionsFactory<>));
services.AddSingleton<IOptionsLoggingSource, OptionsLoggingSource>();
services.AddSingleton<IHostedService, OptionsLoggingService>();
services.AddSingleton<IOptionsFormatter<LoggerFilterOptions>, LoggerFilterOptionsFormatter>();
}
}
}
33 changes: 33 additions & 0 deletions src/Microsoft.Azure.WebJobs.Host/Scale/AggregateScaleStatus.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Collections.Generic;

namespace Microsoft.Azure.WebJobs.Host.Scale
{
/// <summary>
/// Represents the aggregate scale status across all functions being monitored by the host.
/// </summary>
public class AggregateScaleStatus
{
/// <summary>
/// Gets or sets the aggregate scale vote.
/// </summary>
public ScaleVote Vote { get; set; }

/// <summary>
/// Gets or sets the aggregate target worker count.
/// </summary>
public int? TargetWorkerCount { get; set; }

/// <summary>
/// Gets or sets the individual <see cref="ScaleStatus"/>s for all functions being monitored.
/// </summary>
public IDictionary<string, ScaleStatus> FunctionScaleStatuses { get; set; }

/// <summary>
/// Gets or sets the individual <see cref="TargetScalerResult"/>s for all functions being monitored.
/// </summary>
public IDictionary<string, TargetScalerResult> FunctionTargetScalerResults { get; set; }
}
}
28 changes: 28 additions & 0 deletions src/Microsoft.Azure.WebJobs.Host/Scale/IScaleMetricsRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Collections.Generic;
using System.Threading.Tasks;

namespace Microsoft.Azure.WebJobs.Host.Scale
{
/// <summary>
/// Interface defining methods for reading/writing scale metrics to a persistent store.
/// </summary>
public interface IScaleMetricsRepository
{
/// <summary>
/// Persist the metrics for each monitor.
/// </summary>
/// <param name="monitorMetrics">The collection of metrics for each monitor.</param>
/// <returns>A task.</returns>
Task WriteMetricsAsync(IDictionary<IScaleMonitor, ScaleMetrics> monitorMetrics);

/// <summary>
/// Read the metrics.
/// </summary>
/// <param name="monitors">The current collection of monitors.</param>
/// <returns>Map of metrics per monitor.</returns>
Task<IDictionary<IScaleMonitor, IList<ScaleMetrics>>> ReadMetricsAsync(IEnumerable<IScaleMonitor> monitors);
}
}
21 changes: 21 additions & 0 deletions src/Microsoft.Azure.WebJobs.Host/Scale/IScaleStatusProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Text;
using System.Threading.Tasks;

namespace Microsoft.Azure.WebJobs.Host.Scale
{
/// <summary>
/// Interface for providing aggregate scale status across all functions being monitored by the host.
/// </summary>
public interface IScaleStatusProvider
{
/// <summary>
/// Gets the scale status for all functions being monitored by the host.
/// </summary>
/// <param name="context">The <see cref="ScaleStatusContext"/>.</param>
/// <returns>A task that returns the <see cref="AggregateScaleStatus"/>.</returns>
Task<AggregateScaleStatus> GetScaleStatusAsync(ScaleStatusContext context);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Collections.Generic;
using System.Threading.Tasks;

namespace Microsoft.Azure.WebJobs.Host.Scale
{
internal class NullScaleMetricsRepository : IScaleMetricsRepository
{
private IDictionary<IScaleMonitor, IList<ScaleMetrics>> _emptyMetrics = new Dictionary<IScaleMonitor, IList<ScaleMetrics>>();

public Task WriteMetricsAsync(IDictionary<IScaleMonitor, ScaleMetrics> monitorMetrics)
{
return Task.CompletedTask;
}

public Task<IDictionary<IScaleMonitor, IList<ScaleMetrics>>> ReadMetricsAsync(IEnumerable<IScaleMonitor> monitors)
{
return Task.FromResult((IDictionary<IScaleMonitor, IList<ScaleMetrics>>)_emptyMetrics);
}
}
}
Loading