Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 14 additions & 0 deletions Microsoft.DurableTask.sln
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared.AzureManaged.Tests",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleAppMinimal", "samples\ConsoleAppMinimal\ConsoleAppMinimal.csproj", "{B48FACA9-A328-452A-BFAE-C4F60F9C7024}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Worker.OrchestrationServiceShim", "src\Worker\OrchestrationServiceShim\Worker.OrchestrationServiceShim.csproj", "{361E87D2-5CF6-4BB2-8B11-0BE736F88EB8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Worker.OrchestrationServiceShim.Tests", "test\Worker\OrchestrationServiceShim.Tests\Worker.OrchestrationServiceShim.Tests.csproj", "{14822652-388B-4521-924A-2834B75F783C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScheduledTasks", "src\ScheduledTasks\ScheduledTasks.csproj", "{69ED743C-D616-4530-87E2-391D249D7368}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScheduleConsoleApp", "samples\ScheduleConsoleApp\ScheduleConsoleApp.csproj", "{A89B766C-987F-4C9F-8937-D0AB9FE640C8}"
Expand Down Expand Up @@ -231,6 +235,14 @@ Global
{B48FACA9-A328-452A-BFAE-C4F60F9C7024}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B48FACA9-A328-452A-BFAE-C4F60F9C7024}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B48FACA9-A328-452A-BFAE-C4F60F9C7024}.Release|Any CPU.Build.0 = Release|Any CPU
{361E87D2-5CF6-4BB2-8B11-0BE736F88EB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{361E87D2-5CF6-4BB2-8B11-0BE736F88EB8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{361E87D2-5CF6-4BB2-8B11-0BE736F88EB8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{361E87D2-5CF6-4BB2-8B11-0BE736F88EB8}.Release|Any CPU.Build.0 = Release|Any CPU
{14822652-388B-4521-924A-2834B75F783C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{14822652-388B-4521-924A-2834B75F783C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{14822652-388B-4521-924A-2834B75F783C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{14822652-388B-4521-924A-2834B75F783C}.Release|Any CPU.Build.0 = Release|Any CPU
{69ED743C-D616-4530-87E2-391D249D7368}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{69ED743C-D616-4530-87E2-391D249D7368}.Debug|Any CPU.Build.0 = Debug|Any CPU
{69ED743C-D616-4530-87E2-391D249D7368}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down Expand Up @@ -289,6 +301,8 @@ Global
{CECADDB5-E30A-4CE2-8604-9AC596D4A2DC} = {E5637F81-2FB9-4CD7-900D-455363B142A7}
{3272C041-F81D-4C85-A4FB-2A700B5A7A9D} = {CECADDB5-E30A-4CE2-8604-9AC596D4A2DC}
{B48FACA9-A328-452A-BFAE-C4F60F9C7024} = {EFF7632B-821E-4CFC-B4A0-ED4B24296B17}
{361E87D2-5CF6-4BB2-8B11-0BE736F88EB8} = {5B448FF6-EC42-491D-A22E-1DC8B618E6D5}
{14822652-388B-4521-924A-2834B75F783C} = {51DC98A3-0193-4C66-964B-C26C748E25B6}
{69ED743C-D616-4530-87E2-391D249D7368} = {8AFC9781-F6F1-4696-BB4A-9ED7CA9D612B}
{A89B766C-987F-4C9F-8937-D0AB9FE640C8} = {EFF7632B-821E-4CFC-B4A0-ED4B24296B17}
{100348B5-4D97-4A3F-B777-AB14F276F8FE} = {EFF7632B-821E-4CFC-B4A0-ED4B24296B17}
Expand Down
56 changes: 18 additions & 38 deletions src/Client/Core/DurableTaskClientOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ namespace Microsoft.DurableTask.Client;
/// </summary>
public class DurableTaskClientOptions
{
DataConverter dataConverter = JsonDataConverter.Default;
bool enableEntitySupport;
DataConverter? dataConverter;
bool? enableEntitySupport;

/// <summary>
/// Gets or sets the data converter. Default value is <see cref="JsonDataConverter.Default" />.
Expand All @@ -31,34 +31,18 @@ public class DurableTaskClientOptions
/// </remarks>
public DataConverter DataConverter
{
get => this.dataConverter;
set
{
if (value is null)
{
this.dataConverter = JsonDataConverter.Default;
this.DataConverterExplicitlySet = false;
}
else
{
this.dataConverter = value;
this.DataConverterExplicitlySet = true;
}
}
get => this.dataConverter ?? JsonDataConverter.Default;
set => this.dataConverter = value;
}

/// <summary>
/// Gets or sets a value indicating whether this client should support entities. If true, all instance ids starting with '@' are reserved for entities,
/// and validation checks are performed where appropriate.
/// Gets or sets a value indicating whether this client should support entities. If true, all instance ids starting
/// with '@' are reserved for entities, and validation checks are performed where appropriate.
/// </summary>
public bool EnableEntitySupport
{
get => this.enableEntitySupport;
set
{
this.enableEntitySupport = value;
this.EntitySupportExplicitlySet = true;
}
get => this.enableEntitySupport ?? false;
set => this.enableEntitySupport = value;
}

/// <summary>
Expand All @@ -70,12 +54,7 @@ public bool EnableEntitySupport
/// will <b>not</b> resolve it. If not set, we will attempt to resolve it. This is so the
/// behavior is consistently irrespective of option configuration ordering.
/// </remarks>
internal bool DataConverterExplicitlySet { get; private set; }

/// <summary>
/// Gets a value indicating whether <see cref="EnableEntitySupport" /> was explicitly set or not.
/// </summary>
internal bool EntitySupportExplicitlySet { get; private set; }
internal bool DataConverterExplicitlySet => this.dataConverter is not null;

/// <summary>
/// Applies these option values to another.
Expand All @@ -86,15 +65,16 @@ internal void ApplyTo(DurableTaskClientOptions other)
if (other is not null)
{
// Make sure to keep this up to date as values are added.
if (!other.DataConverterExplicitlySet)
{
other.DataConverter = this.DataConverter;
}
ApplyIfSet(this.dataConverter, ref other.dataConverter);
ApplyIfSet(this.enableEntitySupport, ref other.enableEntitySupport);
}
}

if (!other.EntitySupportExplicitlySet)
{
other.EnableEntitySupport = this.EnableEntitySupport;
}
static void ApplyIfSet<T>(T? value, ref T? target)
{
if (value is not null && target is null)
{
target = value;
}
}
}
13 changes: 12 additions & 1 deletion src/Client/OrchestrationServiceClientShim/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,15 @@ Commonly used types:
- `ShimDurableTaskClient`
- `ShimDurableTaskClientOptions`

For more information, see https://github.com/microsoft/durabletask-dotnet
For more information, see https://github.com/microsoft/durabletask-dotnet

## Getting Started

``` CSharp
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

// instantiate this using existing Microsoft.Azure.DurableTask packages.
IOrchestrationServiceClient orchestrationServiceClient = new AzureStorageOrchestrationService(...);
builder.Services.AddDurableTaskClient()
.UseOrchestrationService(orchestrationService);
```
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,20 @@ namespace Microsoft.DurableTask.Worker;
/// <summary>
/// The default builder for durable task.
/// </summary>
public class DefaultDurableTaskWorkerBuilder : IDurableTaskWorkerBuilder
/// <remarks>
/// Initializes a new instance of the <see cref="DefaultDurableTaskWorkerBuilder" /> class.
/// </remarks>
/// <param name="services">The service collection for this builder.</param>
/// <param name="name">The name for this builder.</param>
public class DefaultDurableTaskWorkerBuilder(string? name, IServiceCollection services) : IDurableTaskWorkerBuilder
{
Type? buildTarget;

/// <summary>
/// Initializes a new instance of the <see cref="DefaultDurableTaskWorkerBuilder" /> class.
/// </summary>
/// <param name="services">The service collection for this builder.</param>
/// <param name="name">The name for this builder.</param>
public DefaultDurableTaskWorkerBuilder(string? name, IServiceCollection services)
{
this.Name = name ?? Extensions.Options.Options.DefaultName;
this.Services = Check.NotNull(services);
}

/// <inheritdoc/>
public string Name { get; }
public string Name { get; } = name ?? Extensions.Options.Options.DefaultName;

/// <inheritdoc/>
public IServiceCollection Services { get; }
public IServiceCollection Services { get; } = Check.NotNull(services);

/// <inheritdoc/>
public Type? BuildTarget
Expand Down
87 changes: 63 additions & 24 deletions src/Worker/Core/DurableTaskWorkerOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ namespace Microsoft.DurableTask.Worker;
/// </summary>
public class DurableTaskWorkerOptions
{
DataConverter dataConverter = JsonDataConverter.Default;
DataConverter? dataConverter;
bool? enableEntitySupport;
TimeSpan? maximumTimerInterval;

/// <summary>
/// Gets or sets the data converter. Default value is <see cref="JsonDataConverter.Default" />.
Expand All @@ -28,27 +30,19 @@ public class DurableTaskWorkerOptions
/// </remarks>
public DataConverter DataConverter
{
get => this.dataConverter;
set
{
if (value is null)
{
this.dataConverter = JsonDataConverter.Default;
this.DataConverterExplicitlySet = false;
}
else
{
this.dataConverter = value;
this.DataConverterExplicitlySet = true;
}
}
get => this.dataConverter ?? JsonDataConverter.Default;
set => this.dataConverter = value;
}

/// <summary>
/// Gets or sets a value indicating whether this client should support entities. If true, all instance ids starting
/// with '@' are reserved for entities, and validation checks are performed where appropriate.
/// </summary>
public bool EnableEntitySupport { get; set; }
public bool EnableEntitySupport
{
get => this.enableEntitySupport ?? false;
set => this.enableEntitySupport = value;
}

/// <summary>
/// Gets or sets the maximum timer interval for the
Expand Down Expand Up @@ -81,7 +75,11 @@ public DataConverter DataConverter
/// orchestrations.
/// </para>
/// </remarks>
public TimeSpan MaximumTimerInterval { get; set; } = TimeSpan.FromDays(3);
public TimeSpan MaximumTimerInterval
{
get => this.maximumTimerInterval ?? TimeSpan.FromDays(3);
set => this.maximumTimerInterval = value;
}

/// <summary>
/// Gets options for the Durable Task worker concurrency.
Expand All @@ -102,7 +100,7 @@ public DataConverter DataConverter
/// will <b>not</b> resolve it. If not set, we will attempt to resolve it. This is so the
/// behavior is consistently irrespective of option configuration ordering.
/// </remarks>
internal bool DataConverterExplicitlySet { get; private set; }
internal bool DataConverterExplicitlySet => this.dataConverter is not null;

/// <summary>
/// Applies these option values to another.
Expand All @@ -113,9 +111,18 @@ internal void ApplyTo(DurableTaskWorkerOptions other)
if (other is not null)
{
// Make sure to keep this up to date as values are added.
other.DataConverter = this.DataConverter;
other.MaximumTimerInterval = this.MaximumTimerInterval;
other.EnableEntitySupport = this.EnableEntitySupport;
ApplyIfSet(this.dataConverter, ref other.dataConverter);
ApplyIfSet(this.enableEntitySupport, ref other.enableEntitySupport);
ApplyIfSet(this.maximumTimerInterval, ref other.maximumTimerInterval);
this.Concurrency.ApplyTo(other.Concurrency);
}
}

static void ApplyIfSet<T>(T? value, ref T? target)
{
if (value is not null && target is null)
{
target = value;
}
}

Expand All @@ -124,19 +131,51 @@ internal void ApplyTo(DurableTaskWorkerOptions other)
/// </summary>
public class ConcurrencyOptions
{
static readonly int DefaultMaxConcurrency = 100 * Environment.ProcessorCount;

int? maxActivity;
int? maxOrchestration;
int? maxEntity;

/// <summary>
/// Gets or sets the maximum number of concurrent activity work items that can be processed by the worker.
/// </summary>
public int MaximumConcurrentActivityWorkItems { get; set; } = 100 * Environment.ProcessorCount;
public int MaximumConcurrentActivityWorkItems
{
get => this.maxActivity ?? DefaultMaxConcurrency;
set => this.maxActivity = value;
}

/// <summary>
/// Gets or sets the maximum number of concurrent orchestration work items that can be processed by the worker.
/// </summary>
public int MaximumConcurrentOrchestrationWorkItems { get; set; } = 100 * Environment.ProcessorCount;
public int MaximumConcurrentOrchestrationWorkItems
{
get => this.maxOrchestration ?? DefaultMaxConcurrency;
set => this.maxOrchestration = value;
}

/// <summary>
/// Gets or sets the maximum number of concurrent entity work items that can be processed by the worker.
/// </summary>
public int MaximumConcurrentEntityWorkItems { get; set; } = 100 * Environment.ProcessorCount;
public int MaximumConcurrentEntityWorkItems
{
get => this.maxEntity ?? DefaultMaxConcurrency;
set => this.maxEntity = value;
}

/// <summary>
/// Applies these option values to another.
/// </summary>
/// <param name="other">The options to apply this options values to.</param>
internal void ApplyTo(ConcurrencyOptions other)
{
if (other is not null)
{
ApplyIfSet(this.maxActivity, ref other.maxActivity);
ApplyIfSet(this.maxOrchestration, ref other.maxOrchestration);
ApplyIfSet(this.maxEntity, ref other.maxEntity);
}
}
}
}
22 changes: 8 additions & 14 deletions src/Worker/Core/Hosting/DurableTaskWorker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,21 @@ namespace Microsoft.DurableTask.Worker.Hosting;
/// <summary>
/// Base class for durable workers.
/// </summary>
public abstract class DurableTaskWorker : BackgroundService
/// <remarks>
/// Initializes a new instance of the <see cref="DurableTaskWorker" /> class.
/// </remarks>
/// <param name="name">The name of the worker.</param>
/// <param name="factory">The durable factory.</param>
public abstract class DurableTaskWorker(string? name, IDurableTaskFactory factory) : BackgroundService
{
/// <summary>
/// Initializes a new instance of the <see cref="DurableTaskWorker" /> class.
/// </summary>
/// <param name="name">The name of the worker.</param>
/// <param name="factory">The durable factory.</param>
protected DurableTaskWorker(string? name, IDurableTaskFactory factory)
{
this.Name = name ?? Microsoft.Extensions.Options.Options.DefaultName;
this.Factory = Check.NotNull(factory);
}

/// <summary>
/// Gets the name of this worker.
/// </summary>
protected virtual string Name { get; }
protected virtual string Name { get; } = name ?? Microsoft.Extensions.Options.Options.DefaultName;

/// <summary>
/// Gets the <see cref="IDurableTaskFactory" /> which has been initialized from
/// the configured tasks during host construction.
/// </summary>
protected virtual IDurableTaskFactory Factory { get; }
protected virtual IDurableTaskFactory Factory { get; } = Check.NotNull(factory);
}
2 changes: 1 addition & 1 deletion src/Worker/Core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ Commonly used types:
- `DurableTaskWorkerOptions`
- `IDurableTaskWorkerBuilder`

For more information, see https://github.com/microsoft/durabletask-dotnet
For more information, see https://github.com/microsoft/durabletask-dotnet
24 changes: 9 additions & 15 deletions src/Worker/Core/Shims/DurableTaskShimFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,16 @@ namespace Microsoft.DurableTask.Worker.Shims;
/// This class is intended for use with alternate .NET-based durable task runtimes. It's not intended for use
/// in application code.
/// </remarks>
public class DurableTaskShimFactory
/// <remarks>
/// Initializes a new instance of the <see cref="DurableTaskShimFactory" /> class.
/// </remarks>
/// <param name="options">The data converter.</param>
/// <param name="loggerFactory">The logger factory.</param>
public class DurableTaskShimFactory(
DurableTaskWorkerOptions? options = null, ILoggerFactory? loggerFactory = null)
{
readonly DurableTaskWorkerOptions options;
readonly ILoggerFactory loggerFactory;

/// <summary>
/// Initializes a new instance of the <see cref="DurableTaskShimFactory" /> class.
/// </summary>
/// <param name="options">The data converter.</param>
/// <param name="loggerFactory">The logger factory.</param>
public DurableTaskShimFactory(
DurableTaskWorkerOptions? options = null, ILoggerFactory? loggerFactory = null)
{
this.options = options ?? new();
this.loggerFactory = loggerFactory ?? NullLoggerFactory.Instance;
}
readonly DurableTaskWorkerOptions options = options ?? new();
readonly ILoggerFactory loggerFactory = loggerFactory ?? NullLoggerFactory.Instance;

/// <summary>
/// Gets the default <see cref="DurableTaskShimFactory" /> with default values.
Expand Down
Loading
Loading