-
Notifications
You must be signed in to change notification settings - Fork 636
Initial integration of Durable Task Scheduler (i.e. emulator) #9294
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 5 commits
6b698ba
6cdadb2
1b7b410
ae5c3c2
c436f52
7fbbbfd
7be4aaa
0bcf482
97bd8b2
2bdb505
ac9bbe1
9eb2b7b
c3338d2
6434fed
a7e6a23
76c6941
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>$(DefaultTargetFramework)</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<IsAspireHost>true</IsAspireHost> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<Compile Include="..\..\KnownResourceNames.cs" Link="KnownResourceNames.cs" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<AspireProjectOrPackageReference Include="Aspire.Hosting.AppHost" /> | ||
<AspireProjectOrPackageReference Include="Aspire.Hosting.Azure.Functions" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\DurableTask.Scheduler.WebApi\DurableTask.Scheduler.WebApi.csproj" /> | ||
<ProjectReference Include="..\DurableTask.Scheduler.Worker\DurableTask.Scheduler.Worker.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
using Aspire.Hosting.Azure; | ||
|
||
var builder = DistributedApplication.CreateBuilder(args); | ||
|
||
var scheduler = | ||
builder.AddDurableTaskScheduler("scheduler") | ||
.RunAsEmulator( | ||
options => | ||
{ | ||
options.WithDynamicTaskHubs(); | ||
}); | ||
|
||
var taskHub = scheduler.AddTaskHub("taskhub"); | ||
|
||
var webApi = | ||
builder.AddProject<Projects.DurableTask_Scheduler_WebApi>("webapi") | ||
.WithReference(taskHub); | ||
|
||
builder.AddProject<Projects.DurableTask_Scheduler_Worker>("worker") | ||
.WithReference(webApi) | ||
.WithReference(taskHub); | ||
|
||
builder.Build().Run(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"$schema": "https://json.schemastore.org/launchsettings.json", | ||
"profiles": { | ||
"https": { | ||
"commandName": "Project", | ||
"dotnetRunMessages": true, | ||
"launchBrowser": true, | ||
"applicationUrl": "https://localhost:17222;http://localhost:15079", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development", | ||
"DOTNET_ENVIRONMENT": "Development", | ||
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21093", | ||
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22284" | ||
} | ||
}, | ||
"http": { | ||
"commandName": "Project", | ||
"dotnetRunMessages": true, | ||
"launchBrowser": true, | ||
"applicationUrl": "http://localhost:15079", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development", | ||
"DOTNET_ENVIRONMENT": "Development", | ||
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19250", | ||
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20227" | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"Logging": { | ||
"LogLevel": { | ||
"Default": "Information", | ||
"Microsoft.AspNetCore": "Warning", | ||
"Aspire.Hosting.Dcp": "Warning" | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>$(DefaultTargetFramework)</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<IsAspireHost>true</IsAspireHost> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<Compile Include="..\..\KnownResourceNames.cs" Link="KnownResourceNames.cs" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<AspireProjectOrPackageReference Include="Aspire.Hosting.AppHost" /> | ||
<AspireProjectOrPackageReference Include="Aspire.Hosting.Azure.Functions" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\DurableTask.Scheduler.WebApi\DurableTask.Scheduler.WebApi.csproj" /> | ||
<ProjectReference Include="..\DurableTask.Scheduler.Worker\DurableTask.Scheduler.Worker.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
using Aspire.Hosting.Azure; | ||
|
||
var builder = DistributedApplication.CreateBuilder(args); | ||
|
||
var scheduler = | ||
builder.AddDurableTaskScheduler("scheduler") | ||
.RunAsExisting(builder.AddParameter("scheduler-connection-string")); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this in the sample? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The intent was to have examples that demonstrate the two main DTS scenarios: use of the DTS emulator and use of an existing DTS instance. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One thing I'm having a hard time understanding is the deployment story here. Is this an azure resource as well? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, DTS is an Azure resource (though I'm not intending to support deployment in this initial pass). I did a little experimenting with the Bicep base resource type that other Azure resources are built upon, but they rely on Azure provisioning libraries that do not exist, yet, for DTS. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this model is going to be: |
||
|
||
var taskHub = | ||
scheduler.AddTaskHub("taskhub") | ||
.WithTaskHubName(builder.AddParameter("taskhub-name")); | ||
|
||
var webApi = | ||
builder.AddProject<Projects.DurableTask_Scheduler_WebApi>("webapi") | ||
.WithReference(taskHub); | ||
|
||
builder.AddProject<Projects.DurableTask_Scheduler_Worker>("worker") | ||
.WithReference(webApi) | ||
.WithReference(taskHub); | ||
|
||
builder.Build().Run(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"$schema": "https://json.schemastore.org/launchsettings.json", | ||
"profiles": { | ||
"https": { | ||
"commandName": "Project", | ||
"dotnetRunMessages": true, | ||
"launchBrowser": true, | ||
"applicationUrl": "https://localhost:17222;http://localhost:15079", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development", | ||
"DOTNET_ENVIRONMENT": "Development", | ||
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21093", | ||
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22284" | ||
} | ||
}, | ||
"http": { | ||
"commandName": "Project", | ||
"dotnetRunMessages": true, | ||
"launchBrowser": true, | ||
"applicationUrl": "http://localhost:15079", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development", | ||
"DOTNET_ENVIRONMENT": "Development", | ||
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19250", | ||
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20227" | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"Logging": { | ||
"LogLevel": { | ||
"Default": "Information", | ||
"Microsoft.AspNetCore": "Warning", | ||
"Aspire.Hosting.Dcp": "Warning" | ||
} | ||
}, | ||
"Parameters": { | ||
"scheduler-connection-string": "<connection string>", | ||
"taskhub-name": "<name>" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>$(DefaultTargetFramework)</TargetFramework> | ||
<Nullable>enable</Nullable> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\Playground.ServiceDefaults\Playground.ServiceDefaults.csproj" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.DurableTask.Client.AzureManaged" /> | ||
</ItemGroup> | ||
|
||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
@HostAddress = http://localhost:5142 | ||
|
||
POST {{HostAddress}}/create | ||
Content-Type: application/json | ||
|
||
{ | ||
"text": "hello world" | ||
} | ||
|
||
### | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,47 @@ | ||||||
using Microsoft.AspNetCore.Mvc; | ||||||
using Microsoft.DurableTask.Client; | ||||||
using Microsoft.DurableTask.Client.AzureManaged; | ||||||
using System.Text.Json.Serialization; | ||||||
|
||||||
var builder = WebApplication.CreateBuilder(args); | ||||||
|
||||||
builder.AddServiceDefaults(); | ||||||
|
||||||
builder.Services.AddDurableTaskClient( | ||||||
clientBuilder => | ||||||
{ | ||||||
clientBuilder.UseDurableTaskScheduler( | ||||||
builder.Configuration.GetConnectionString("taskhub") ?? throw new InvalidOperationException("Scheduler connection string not configured."), | ||||||
options => | ||||||
{ | ||||||
options.AllowInsecureCredentials = true; | ||||||
}); | ||||||
Comment on lines
+13
to
+18
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we build a client integration? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ...yes? It's complicated because consuming applications can be either DTS "clients" or "workers" (and sometimes both), and there are separate SDKs for each which means multiple client integrations. Also, there are two sets of SDKs that apps can use (and you might consider another scenario a third) which further expands the matrix. I'd say we should start with client integrations for the "modern" SDK, worker first and then client, as the former is the most common. Then, if there's demand, look at integrations for the "older" SDKs. That said, any client integrations would be follow up PRs. |
||||||
}); | ||||||
|
||||||
var app = builder.Build(); | ||||||
|
||||||
app.MapPost("/create", async ([FromBody] EchoValue value, [FromServices] DurableTaskClient durableTaskClient) => | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It magically knows!
Suggested change
|
||||||
{ | ||||||
string instanceId = await durableTaskClient.ScheduleNewOrchestrationInstanceAsync( | ||||||
"Echo", | ||||||
value); | ||||||
|
||||||
await durableTaskClient.WaitForInstanceCompletionAsync(instanceId); | ||||||
|
||||||
return Results.Ok(); | ||||||
}) | ||||||
.WithName("CreateOrchestration"); | ||||||
|
||||||
app.MapPost("/echo", ([FromBody] EchoValue value) => | ||||||
{ | ||||||
return new EchoValue { Text = $"Echoed: {value.Text}" }; | ||||||
}) | ||||||
.WithName("EchoText"); | ||||||
|
||||||
app.Run(); | ||||||
|
||||||
public record EchoValue | ||||||
{ | ||||||
[JsonPropertyName("text")] | ||||||
public required string Text { get; init; } | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"$schema": "https://json.schemastore.org/launchsettings.json", | ||
"profiles": { | ||
"http": { | ||
"commandName": "Project", | ||
"dotnetRunMessages": true, | ||
"launchBrowser": false, | ||
"applicationUrl": "http://localhost:5142", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"Logging": { | ||
"LogLevel": { | ||
"Default": "Information", | ||
"Microsoft.AspNetCore": "Warning" | ||
} | ||
}, | ||
"AllowedHosts": "*" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.Worker"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>$(DefaultTargetFramework)</TargetFramework> | ||
<Nullable>enable</Nullable> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.DurableTask.Worker.AzureManaged" /> | ||
<PackageReference Include="Microsoft.Extensions.Hosting" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\Playground.ServiceDefaults\Playground.ServiceDefaults.csproj" /> | ||
</ItemGroup> | ||
</Project> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this explicit call needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just as a demonstration of configuring options on the emulator. (Not every Aspire application will want to use dynamic task hub names.)