-
Notifications
You must be signed in to change notification settings - Fork 536
Workflow tutorials C# #1182
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: master
Are you sure you want to change the base?
Workflow tutorials C# #1182
Conversation
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
c6914e5
to
72668f5
Compare
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
Signed-off-by: Marc Duiker <[email protected]>
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.
Several changes for .NET syntax and formatting changes (e.g. use var
, primary constructors and static classes for constants), improvements to how instances should be injected from DI and
{ | ||
// Do use these deterministic methods and properties on the WorkflowContext instead. | ||
// These operations create the same value when the workflow is replayed. | ||
var orderId = context.NewGuid().ToString(); |
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.
This isn't deterministic
public override async Task<InventoryResult> RunAsync(WorkflowActivityContext context, OrderItem orderItem) | ||
{ | ||
// Beware of non-idempotent operations in an activity. | ||
// Dapr Workflow guarantees at-least-once execution of activities, so activities might be executed more than once. |
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.
While true, I'd supplement with some context in that if the workflow activity successfully returns a value, it will not be run again as its value will be used from the workflow context. This makes for a better argument then that workflows should do as little as possible so they improve their success rate and minimize being executed more than once (but should they be, yes, designing for idempotency would be ideal).
} | ||
} | ||
|
||
internal sealed record OrderItem(string Id, string Description, double UnitPrice, int Quantity); |
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.
As the OrderItem's ID was previously created from a Guid, there's little reason the ID couldn't just remain a GUID all the way through.
{ | ||
public override async Task<int> RunAsync(WorkflowContext context, string orderItem) | ||
{ | ||
int resultA = await context.CallActivityAsync<int>( |
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.
It's far more common for developers to use var
as in var resultA
instead of repeating the type.
/// If there are in-flight workflow instances that were started with the previous version | ||
/// of this workflow, these will fail when the new version of the workflow is deployed | ||
/// and the workflow name remains the same, since the runtime parameters do not match with the persisted state. | ||
/// It is recommended to version workflows by creating a new workflow class with a new name: |
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.
Might also mention something about avoiding use of perpetual workflows as this removes the opportunity to swap out workflows.
|
||
app.MapPost("/terminate/{instanceId}", async (string instanceId) => { | ||
await using var scope = app.Services.CreateAsyncScope(); | ||
var workflowClient = scope.ServiceProvider.GetRequiredService<DaprWorkflowClient>(); |
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.
Nope, see above
}); | ||
|
||
app.MapPost("/resume/{instanceId}", async (string instanceId) => { | ||
await using var scope = app.Services.CreateAsyncScope(); |
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.
Nope, see above
|
||
app.MapPost("/suspend/{instanceId}", async (string instanceId) => { | ||
await using var scope = app.Services.CreateAsyncScope(); | ||
var workflowClient = scope.ServiceProvider.GetRequiredService<DaprWorkflowClient>(); |
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.
Nope, see above
|
||
app.MapGet("/status/{instanceId}", async (string instanceId) => { | ||
await using var scope = app.Services.CreateAsyncScope(); | ||
var workflowClient = scope.ServiceProvider.GetRequiredService<DaprWorkflowClient>(); |
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.
Nope, see above
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Dapr.Workflow" Version="1.15.2" /> |
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.
Version bump
Description
This PR adds workflow examples for C# in the tutorials folder.
Issue reference
We strive to have all PRs being opened based on an issue, where the problem or feature have been discussed prior to implementation.
Please reference the issue this PR will close: #1183
Checklist
Please make sure you've completed the relevant tasks for this PR, out of the following list: