Skip to content

Commit 37e6ed3

Browse files
committed
non-breaking
1 parent fbd0cee commit 37e6ed3

25 files changed

+746
-33
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net6.0</TargetFramework>
6+
<Nullable>disable</Nullable>
7+
<UserSecretsId>25384414-13b6-4ef1-8eeb-12236bcf0bcd</UserSecretsId>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="Microsoft.Azure.DurableTask.Core" />
12+
<PackageReference Include="Microsoft.Azure.DurableTask.Emulator" />
13+
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" />
14+
<PackageReference Include="Microsoft.Extensions.Hosting" />
15+
</ItemGroup>
16+
17+
<ItemGroup>
18+
<ProjectReference Include="..\..\src\DurableTask.Hosting\src\DurableTask.Hosting.csproj" />
19+
</ItemGroup>
20+
21+
</Project>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) Jacob Viau. All rights reserved.
2+
// Licensed under the APACHE 2.0. See LICENSE file in the project root for full license information.
3+
4+
using DurableTask.Core;
5+
6+
namespace DurableTask.Named.Samples.Generics;
7+
8+
/// <summary>
9+
/// An example of an open generic activity.
10+
/// </summary>
11+
/// <typeparam name="T">The open generic type.</typeparam>
12+
public class GenericActivity<T> : TaskActivity<T, string>
13+
{
14+
/// <inheritdoc />
15+
protected override string Execute(TaskContext context, T input)
16+
{
17+
return $"My generic param is {typeof(T)} with value '{input}'";
18+
}
19+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright (c) Jacob Viau. All rights reserved.
2+
// Licensed under the APACHE 2.0. See LICENSE file in the project root for full license information.
3+
4+
using DurableTask.Core;
5+
6+
namespace DurableTask.Named.Samples.Generics;
7+
8+
/// <summary>
9+
/// Runner for generic tasks example.
10+
/// </summary>
11+
public class GenericOrchestrationRunner : TaskOrchestration<string, string>
12+
{
13+
/// <inheritdoc />
14+
public override async Task<string> RunTask(OrchestrationContext context, string input)
15+
{
16+
string result = await context.ScheduleTask<string>(typeof(GenericActivity<int>), 10);
17+
await PrintAsync(context, result);
18+
19+
result = await context.ScheduleTask<string>(typeof(GenericActivity<string>), "example");
20+
await PrintAsync(context, result);
21+
22+
result = await context.ScheduleTask<string>(typeof(GenericActivity<MyClass>), new MyClass());
23+
await PrintAsync(context, result);
24+
25+
return string.Empty;
26+
}
27+
28+
private static Task<string> PrintAsync(OrchestrationContext context, string input)
29+
{
30+
return context.ScheduleTask<string>(typeof(PrintTask), input);
31+
}
32+
33+
private class MyClass
34+
{
35+
public override string ToString() => "Example private class";
36+
}
37+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright (c) Jacob Viau. All rights reserved.
2+
// Licensed under the APACHE 2.0. See LICENSE file in the project root for full license information.
3+
4+
using DurableTask.Core;
5+
6+
namespace DurableTask.Named.Samples.Greetings;
7+
8+
/// <summary>
9+
/// A task activity for getting a username from console.
10+
/// </summary>
11+
public class GetUserTask : TaskActivity<string, string>
12+
{
13+
private readonly IConsole _console;
14+
15+
/// <summary>
16+
/// Initializes a new instance of the <see cref="GetUserTask"/> class.
17+
/// </summary>
18+
/// <param name="console">The console output helper.</param>
19+
public GetUserTask(IConsole console)
20+
{
21+
_console = console ?? throw new ArgumentNullException(nameof(console));
22+
}
23+
24+
/// <inheritdoc />
25+
protected override string Execute(TaskContext context, string input)
26+
{
27+
_console.WriteLine("Please enter your name:");
28+
return _console.ReadLine();
29+
}
30+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright (c) Jacob Viau. All rights reserved.
2+
// Licensed under the APACHE 2.0. See LICENSE file in the project root for full license information.
3+
4+
using DurableTask.Core;
5+
6+
namespace DurableTask.Named.Samples.Greetings;
7+
8+
/// <summary>
9+
/// A task orchestration for greeting a user.
10+
/// </summary>
11+
public class GreetingsOrchestration : TaskOrchestration<string, string>
12+
{
13+
/// <inheritdoc />
14+
public override async Task<string> RunTask(OrchestrationContext context, string input)
15+
{
16+
string user = await context.ScheduleTask<string>(typeof(GetUserTask));
17+
string greeting = await context.ScheduleTask<string>(typeof(SendGreetingTask), user);
18+
return greeting;
19+
}
20+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright (c) Jacob Viau. All rights reserved.
2+
// Licensed under the APACHE 2.0. See LICENSE file in the project root for full license information.
3+
4+
using DurableTask.Core;
5+
6+
namespace DurableTask.Named.Samples.Greetings;
7+
8+
/// <summary>
9+
/// A task for sending a greeting.
10+
/// </summary>
11+
public sealed class SendGreetingTask : AsyncTaskActivity<string, string>
12+
{
13+
private readonly IConsole _console;
14+
15+
/// <summary>
16+
/// Initializes a new instance of the <see cref="SendGreetingTask"/> class.
17+
/// </summary>
18+
/// <param name="console">The console output helper.</param>
19+
public SendGreetingTask(IConsole console)
20+
{
21+
_console = console ?? throw new ArgumentNullException(nameof(console));
22+
}
23+
24+
/// <inheritdoc />
25+
protected override async Task<string> ExecuteAsync(TaskContext context, string user)
26+
{
27+
string message;
28+
if (!string.IsNullOrWhiteSpace(user) && user.Equals("TimedOut"))
29+
{
30+
message = "GetUser Timed out!!!";
31+
_console.WriteLine(message);
32+
}
33+
else
34+
{
35+
_console.WriteLine("Sending greetings to user: " + user + "...");
36+
await Task.Delay(5 * 1000);
37+
message = "Greeting sent to " + user;
38+
_console.WriteLine(message);
39+
}
40+
41+
return message;
42+
}
43+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright (c) Jacob Viau. All rights reserved.
2+
// Licensed under the APACHE 2.0. See LICENSE file in the project root for full license information.
3+
4+
using DurableTask.Core;
5+
6+
namespace DurableTask.Named.Samples;
7+
8+
/// <summary>
9+
/// An activity to print to the console.
10+
/// </summary>
11+
public class PrintTask : TaskActivity<string, string>
12+
{
13+
private readonly IConsole _console;
14+
15+
/// <summary>
16+
/// Initializes a new instance of the <see cref="PrintTask"/> class.
17+
/// </summary>
18+
/// <param name="console">The console to print to.</param>
19+
public PrintTask(IConsole console)
20+
{
21+
_console = console ?? throw new ArgumentNullException(nameof(console));
22+
}
23+
24+
/// <inheritdoc />
25+
protected override string Execute(TaskContext context, string input)
26+
{
27+
_console.WriteLine(input);
28+
return string.Empty;
29+
}
30+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// Copyright (c) Jacob Viau. All rights reserved.
2+
// Licensed under the APACHE 2.0. See LICENSE file in the project root for full license information.
3+
4+
using DurableTask.Core;
5+
using DurableTask.DependencyInjection;
6+
using DurableTask.Emulator;
7+
using DurableTask.Hosting;
8+
using DurableTask.Hosting.Options;
9+
using DurableTask.Named.Samples.Generics;
10+
using DurableTask.Named.Samples.Greetings;
11+
using Microsoft.Extensions.Configuration;
12+
using Microsoft.Extensions.DependencyInjection;
13+
using Microsoft.Extensions.Hosting;
14+
using DurableTask.DependencyInjection.Extensions;
15+
16+
namespace DurableTask.Named.Samples;
17+
18+
/// <summary>
19+
/// The samples program.
20+
/// </summary>
21+
public class Program
22+
{
23+
private static readonly string s_taskHubName = "myHub";
24+
25+
/// <summary>
26+
/// The entry point.
27+
/// </summary>
28+
/// <param name="args">The supplied arguments, if any.</param>
29+
/// <returns>A task that completes when this program is finished running.</returns>
30+
public static Task Main(string[] args)
31+
{
32+
IHost host = Host.CreateDefaultBuilder(args)
33+
.ConfigureAppConfiguration(builder => builder.AddUserSecrets<Program>())
34+
.ConfigureServices(services =>
35+
{
36+
IOrchestrationService orchestrationService = UseLocalEmulator();
37+
38+
services.AddTaskHubWorker(s_taskHubName, (builder) =>
39+
{
40+
builder
41+
.UseBuildTarget<DurableTaskHubWorker>()
42+
.WithOrchestrationService(orchestrationService)
43+
44+
.UseOrchestrationMiddleware<SampleMiddleware>()
45+
.UseActivityMiddleware<SampleMiddleware>()
46+
47+
.AddOrchestration<GreetingsOrchestration>()
48+
.AddOrchestration<GenericOrchestrationRunner>()
49+
.AddActivitiesFromAssembly<Program>();
50+
});
51+
services.AddTaskHubClient(s_taskHubName, (builder) =>
52+
{
53+
builder
54+
.UseBuildTarget<DurableTaskHubClient>()
55+
.WithOrchestrationService((IOrchestrationServiceClient)orchestrationService);
56+
});
57+
services.Configure<TaskHubOptions>(opt =>
58+
{
59+
opt.CreateIfNotExists = true;
60+
});
61+
services.AddSingleton<IConsole, ConsoleWrapper>();
62+
services.AddHostedService<TaskEnqueuer>();
63+
})
64+
.UseConsoleLifetime()
65+
.Build();
66+
67+
return host.RunAsync();
68+
}
69+
70+
private static IOrchestrationService UseLocalEmulator()
71+
=> new LocalOrchestrationService();
72+
73+
private class TaskEnqueuer : BackgroundService
74+
{
75+
private readonly TaskHubClient _client;
76+
private readonly IConsole _console;
77+
private readonly string _instanceId = Guid.NewGuid().ToString();
78+
79+
public TaskEnqueuer(ITaskHubClientProvider clientProvider, IConsole console)
80+
{
81+
_client = ((DurableTaskHubClient)clientProvider.GetClient(s_taskHubName)).Client;
82+
_console = console ?? throw new ArgumentNullException(nameof(console));
83+
}
84+
85+
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
86+
{
87+
OrchestrationInstance instance = await _client.CreateOrchestrationInstanceAsync(
88+
NameVersionHelper.GetDefaultName(typeof(GenericOrchestrationRunner)),
89+
NameVersionHelper.GetDefaultVersion(typeof(GenericOrchestrationRunner)),
90+
_instanceId,
91+
null,
92+
new Dictionary<string, string>()
93+
{
94+
["CorrelationId"] = Guid.NewGuid().ToString(),
95+
});
96+
97+
OrchestrationState result = await _client.WaitForOrchestrationAsync(
98+
instance, TimeSpan.FromSeconds(60), stoppingToken);
99+
100+
_console.WriteLine();
101+
_console.WriteLine($"Orchestration finished.");
102+
_console.WriteLine($"Run stats: {result.Status}");
103+
_console.WriteLine("Press Ctrl+C to exit");
104+
}
105+
}
106+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"profiles": {
3+
"DurableTask.Named.Samples": {
4+
"commandName": "Project",
5+
"environmentVariables": {
6+
"DOTNET_ENVIRONMENT": "Development"
7+
}
8+
}
9+
}
10+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using DurableTask.Core.Middleware;
2+
using DurableTask.DependencyInjection;
3+
4+
namespace DurableTask.Named.Samples;
5+
6+
/// <summary>
7+
/// Sample middleware
8+
/// </summary>
9+
public class SampleMiddleware : ITaskMiddleware
10+
{
11+
private readonly IConsole _console;
12+
13+
/// <summary>
14+
/// Initializes a new instance of the <see cref="SampleMiddleware"/> class.
15+
/// </summary>
16+
/// <param name="console">The console output helper.</param>
17+
public SampleMiddleware(IConsole console)
18+
{
19+
_console = console;
20+
}
21+
22+
/// <inheritdoc />
23+
public Task InvokeAsync(DispatchMiddlewareContext context, Func<Task> next)
24+
{
25+
_console.WriteLine("In sample middleware. Dependency Injection works.");
26+
return next();
27+
}
28+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) Jacob Viau. All rights reserved.
2+
// Licensed under the APACHE 2.0. See LICENSE file in the project root for full license information.
3+
4+
namespace System;
5+
6+
/// <summary>
7+
/// Default implementation of <see cref="IConsole"/>.
8+
/// </summary>
9+
public class ConsoleWrapper : IConsole
10+
{
11+
/// <inheritdoc />
12+
public string ReadLine() => Console.ReadLine();
13+
14+
/// <inheritdoc />
15+
public void WriteLine() => Console.WriteLine();
16+
17+
/// <inheritdoc />
18+
public void WriteLine(string line) => Console.WriteLine(line);
19+
}

0 commit comments

Comments
 (0)