Skip to content

Commit 22ce618

Browse files
authored
Add Client.OrchestrationServiceClientShim (#102)
1 parent be3c6c5 commit 22ce618

18 files changed

+1045
-71
lines changed

Microsoft.DurableTask.sln

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shared", "src\Shared\Shared
5757
EndProject
5858
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "misc", "misc\misc.csproj", "{1E135970-60CF-470A-9270-4560BFA0A7DF}"
5959
EndProject
60+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client.OrchestrationServiceClientShim", "src\Client\OrchestrationServiceClientShim\Client.OrchestrationServiceClientShim.csproj", "{505F6151-6E36-4E0A-A740-14751B8A9397}"
61+
EndProject
62+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client.OrchestrationServiceClientShim.Tests", "test\Client\OrchestrationServiceClientShim.Tests\Client.OrchestrationServiceClientShim.Tests.csproj", "{93E3B973-0FC4-4241-B7BB-064FB538FB50}"
63+
EndProject
6064
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc", "src\Grpc\Grpc.csproj", "{44AD321D-96D4-481E-BD41-D0B12A619833}"
6165
EndProject
6266
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmarks", "test\Benchmarks\Benchmarks.csproj", "{82C0CD7D-2764-421A-8256-7E2304D5A6E7}"
@@ -147,6 +151,14 @@ Global
147151
{1E135970-60CF-470A-9270-4560BFA0A7DF}.Debug|Any CPU.Build.0 = Debug|Any CPU
148152
{1E135970-60CF-470A-9270-4560BFA0A7DF}.Release|Any CPU.ActiveCfg = Release|Any CPU
149153
{1E135970-60CF-470A-9270-4560BFA0A7DF}.Release|Any CPU.Build.0 = Release|Any CPU
154+
{505F6151-6E36-4E0A-A740-14751B8A9397}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
155+
{505F6151-6E36-4E0A-A740-14751B8A9397}.Debug|Any CPU.Build.0 = Debug|Any CPU
156+
{505F6151-6E36-4E0A-A740-14751B8A9397}.Release|Any CPU.ActiveCfg = Release|Any CPU
157+
{505F6151-6E36-4E0A-A740-14751B8A9397}.Release|Any CPU.Build.0 = Release|Any CPU
158+
{93E3B973-0FC4-4241-B7BB-064FB538FB50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
159+
{93E3B973-0FC4-4241-B7BB-064FB538FB50}.Debug|Any CPU.Build.0 = Debug|Any CPU
160+
{93E3B973-0FC4-4241-B7BB-064FB538FB50}.Release|Any CPU.ActiveCfg = Release|Any CPU
161+
{93E3B973-0FC4-4241-B7BB-064FB538FB50}.Release|Any CPU.Build.0 = Release|Any CPU
150162
{44AD321D-96D4-481E-BD41-D0B12A619833}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
151163
{44AD321D-96D4-481E-BD41-D0B12A619833}.Debug|Any CPU.Build.0 = Debug|Any CPU
152164
{44AD321D-96D4-481E-BD41-D0B12A619833}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -183,6 +195,8 @@ Global
183195
{8A0156E6-F033-49AB-AB0C-6698CE1DB24F} = {EFF7632B-821E-4CFC-B4A0-ED4B24296B17}
184196
{21AF0D71-6D32-483F-B6E8-3B28EE432560} = {EFF7632B-821E-4CFC-B4A0-ED4B24296B17}
185197
{57A4C812-B0D9-49E9-9EBE-7E94D3D78ED7} = {8AFC9781-F6F1-4696-BB4A-9ED7CA9D612B}
198+
{505F6151-6E36-4E0A-A740-14751B8A9397} = {1C217BB2-CE16-41CC-9D47-0FC0DB60BDB3}
199+
{93E3B973-0FC4-4241-B7BB-064FB538FB50} = {5AD837BC-78F3-4543-8AA3-DF74D0DF94C0}
186200
{44AD321D-96D4-481E-BD41-D0B12A619833} = {8AFC9781-F6F1-4696-BB4A-9ED7CA9D612B}
187201
{82C0CD7D-2764-421A-8256-7E2304D5A6E7} = {E5637F81-2FB9-4CD7-900D-455363B142A7}
188202
EndGlobalSection

src/Client/Core/Client.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,8 @@ The client is responsible for interacting with orchestrations from outside the w
2121
<ProjectReference Include="../../Abstractions/Abstractions.csproj" />
2222
</ItemGroup>
2323

24+
<ItemGroup>
25+
<SharedSection Include="DependencyInjection" />
26+
</ItemGroup>
27+
2428
</Project>

src/Client/Core/DependencyInjection/ServiceProviderExtensions.cs

Lines changed: 0 additions & 28 deletions
This file was deleted.

src/Client/Core/OrchestrationRuntimeStatus.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public enum OrchestrationRuntimeStatus
4646
Pending,
4747

4848
/// <summary>
49-
/// The orchestration is in a suspended state.
49+
/// The orchestration has been suspended.
5050
/// </summary>
5151
Suspended,
5252
}

src/Client/Grpc/Client.Grpc.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
<ItemGroup>
2525
<SharedSection Include="Core" />
26+
<SharedSection Include="DependencyInjection" />
2627
<SharedSection Include="Grpc" />
2728
</ItemGroup>
2829

src/Client/Grpc/DependencyInjection/DurableTaskClientBuilderExtensions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ public static IDurableTaskClientBuilder UseGrpc(this IDurableTaskClientBuilder b
5858
public static IDurableTaskClientBuilder UseGrpc(
5959
this IDurableTaskClientBuilder builder, Action<GrpcDurableTaskClientOptions> configure)
6060
{
61+
Check.NotNull(builder);
62+
Check.NotNull(configure);
6163
builder.Services.Configure(builder.Name, configure);
6264
return builder.UseBuildTarget<GrpcDurableTaskClient, GrpcDurableTaskClientOptions>();
6365
}

src/Client/Grpc/DependencyInjection/ServiceProviderExtensions.cs

Lines changed: 0 additions & 28 deletions
This file was deleted.

src/Client/Grpc/GrpcDurableTaskClient.cs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,8 @@ public override async Task<string> ScheduleNewOrchestrationInstanceAsync(
9595
public override async Task RaiseEventAsync(
9696
string instanceId, string eventName, object? eventPayload = null, CancellationToken cancellation = default)
9797
{
98-
if (string.IsNullOrEmpty(instanceId))
99-
{
100-
throw new ArgumentNullException(nameof(instanceId));
101-
}
102-
103-
if (string.IsNullOrEmpty(eventName))
104-
{
105-
throw new ArgumentNullException(nameof(eventName));
106-
}
98+
Check.NotNullOrEmpty(instanceId);
99+
Check.NotNullOrEmpty(eventName);
107100

108101
P.RaiseEventRequest request = new()
109102
{
@@ -119,11 +112,7 @@ public override async Task RaiseEventAsync(
119112
public override async Task TerminateInstanceAsync(
120113
string instanceId, object? output = null, CancellationToken cancellation = default)
121114
{
122-
if (string.IsNullOrEmpty(instanceId))
123-
{
124-
throw new ArgumentNullException(nameof(instanceId));
125-
}
126-
115+
Check.NotNullOrEmpty(instanceId);
127116
this.logger.TerminatingInstance(instanceId);
128117

129118
string? serializedOutput = this.DataConverter.Serialize(output);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.0</TargetFramework>
5+
<PackageDescription>The compatibility shim client for the Durable Task Framework. Allows for using a `IOrchestrationServiceClient` directly.
6+
7+
The client is responsible for interacting with orchestrations from outside the worker.</PackageDescription>
8+
<EnableStyleCop>true</EnableStyleCop>
9+
</PropertyGroup>
10+
11+
<!-- Version info -->
12+
<PropertyGroup>
13+
<VersionPrefix>1.0.0</VersionPrefix>
14+
<VersionSuffix>rc.1</VersionSuffix>
15+
</PropertyGroup>
16+
17+
<ItemGroup>
18+
<ProjectReference Include="../Core/Client.csproj" />
19+
</ItemGroup>
20+
21+
<ItemGroup>
22+
<SharedSection Include="Core" />
23+
<SharedSection Include="DependencyInjection" />
24+
</ItemGroup>
25+
26+
</Project>
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using DurableTask.Core;
5+
using Microsoft.DurableTask.Client.OrchestrationServiceClientShim;
6+
using Microsoft.Extensions.DependencyInjection;
7+
8+
namespace Microsoft.DurableTask.Client;
9+
10+
/// <summary>
11+
/// Extension methods for adding Durable Task support to .NET hosted services, such as ASP.NET Core hosts.
12+
/// </summary>
13+
public static class DurableTaskClientBuilderExtensions
14+
{
15+
/// <summary>Configures the <see cref="IDurableTaskClientBuilder" /> to be a client backed by a
16+
/// <see cref="IOrchestrationServiceClient" />.
17+
/// </summary>
18+
/// <remarks>
19+
/// This must be called independently of worker registration.
20+
/// </remarks>
21+
/// <param name="builder">The builder to configure.</param>
22+
/// <returns>The original builder, for call chaining.</returns>
23+
public static IDurableTaskClientBuilder UseOrchestrationService(this IDurableTaskClientBuilder builder)
24+
=> builder.UseOrchestrationService(opt => { });
25+
26+
/// <summary>
27+
/// Configures the <see cref="IDurableTaskClientBuilder" /> to be a client backed by a
28+
/// <see cref="IOrchestrationServiceClient" />.
29+
/// </summary>
30+
/// <remarks>
31+
/// This must be called independently of worker registration.
32+
/// </remarks>
33+
/// <param name="builder">The builder to configure.</param>
34+
/// <param name="client">The orchestration service client to use.</param>
35+
/// <returns>The original builder, for call chaining.</returns>
36+
public static IDurableTaskClientBuilder UseOrchestrationService(
37+
this IDurableTaskClientBuilder builder, IOrchestrationServiceClient client)
38+
=> builder.UseOrchestrationService(opt =>
39+
{
40+
opt.Client = client;
41+
});
42+
43+
/// <summary>Configures the <see cref="IDurableTaskClientBuilder" /> to be a client backed by a
44+
/// <see cref="IOrchestrationServiceClient" />.
45+
/// </summary>
46+
/// <remarks>
47+
/// This must be called independently of worker registration.
48+
/// </remarks>
49+
/// <param name="builder">The builder to configure.</param>
50+
/// <param name="configure">The action to configure the client options.</param>
51+
/// <returns>The original builder, for call chaining.</returns>
52+
public static IDurableTaskClientBuilder UseOrchestrationService(
53+
this IDurableTaskClientBuilder builder, Action<ShimDurableTaskClientOptions> configure)
54+
{
55+
Check.NotNull(builder);
56+
Check.NotNull(configure);
57+
builder.Services.Configure(builder.Name, configure);
58+
builder.Services.AddOptions<ShimDurableTaskClientOptions>(builder.Name)
59+
.PostConfigure<IServiceProvider>((opt, sp) =>
60+
{
61+
if (opt.Client is not null)
62+
{
63+
return;
64+
}
65+
66+
// Try to resolve client from service container.
67+
opt.Client = sp.GetService<IOrchestrationServiceClient>()
68+
?? sp.GetService<IOrchestrationService>() as IOrchestrationServiceClient;
69+
})
70+
.Validate(x => x.Client is not null, "ShimDurableTaskClientOptions.Client must not be null.");
71+
72+
return builder.UseBuildTarget<ShimDurableTaskClient, ShimDurableTaskClientOptions>();
73+
}
74+
}

0 commit comments

Comments
 (0)