-
Notifications
You must be signed in to change notification settings - Fork 530
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1130 from WhitWaldo/workflow-dotnet
Modernized and updated Dapr Workflows .NET quickstart
- Loading branch information
Showing
9 changed files
with
259 additions
and
265 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 14 additions & 20 deletions
34
workflows/csharp/sdk/order-processor/Activities/NotifyActivity.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,19 @@ | ||
namespace WorkflowConsoleApp.Activities | ||
{ | ||
using System.Threading.Tasks; | ||
using Dapr.Workflow; | ||
using Microsoft.Extensions.Logging; | ||
namespace WorkflowConsoleApp.Activities; | ||
|
||
record Notification(string Message); | ||
using System.Threading.Tasks; | ||
using Dapr.Workflow; | ||
using Microsoft.Extensions.Logging; | ||
|
||
class NotifyActivity : WorkflowActivity<Notification, object> | ||
internal sealed partial class NotifyActivity(ILogger<NotifyActivity> logger) : WorkflowActivity<Notification, object?> | ||
{ | ||
public override Task<object?> RunAsync(WorkflowActivityContext context, Notification notification) | ||
{ | ||
readonly ILogger logger; | ||
|
||
public NotifyActivity(ILoggerFactory loggerFactory) | ||
{ | ||
this.logger = loggerFactory.CreateLogger<NotifyActivity>(); | ||
} | ||
|
||
public override Task<object> RunAsync(WorkflowActivityContext context, Notification notification) | ||
{ | ||
this.logger.LogInformation(notification.Message); | ||
|
||
return Task.FromResult<object>(null); | ||
} | ||
LogNotification(logger, notification); | ||
return Task.FromResult<object?>(null); | ||
} | ||
|
||
[LoggerMessage(LogLevel.Information, "Presenting notification {notification}")] | ||
static partial void LogNotification(ILogger logger, Notification notification); | ||
} | ||
|
||
internal sealed record Notification(string Message); |
56 changes: 22 additions & 34 deletions
56
workflows/csharp/sdk/order-processor/Activities/ProcessPaymentActivity.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,28 @@ | ||
namespace WorkflowConsoleApp.Activities | ||
{ | ||
using System.Threading.Tasks; | ||
using Dapr.Client; | ||
using Dapr.Workflow; | ||
using Microsoft.Extensions.Logging; | ||
using WorkflowConsoleApp.Models; | ||
using System; | ||
namespace WorkflowConsoleApp.Activities; | ||
|
||
class ProcessPaymentActivity : WorkflowActivity<PaymentRequest, object> | ||
{ | ||
readonly ILogger logger; | ||
readonly DaprClient client; | ||
using System.Threading.Tasks; | ||
using Dapr.Client; | ||
using Dapr.Workflow; | ||
using Microsoft.Extensions.Logging; | ||
using Models; | ||
using System; | ||
|
||
public ProcessPaymentActivity(ILoggerFactory loggerFactory, DaprClient client) | ||
{ | ||
this.logger = loggerFactory.CreateLogger<ProcessPaymentActivity>(); | ||
this.client = client; | ||
} | ||
internal sealed partial class ProcessPaymentActivity(ILogger<ProcessPaymentActivity> logger) : WorkflowActivity<PaymentRequest, object?> | ||
{ | ||
public override async Task<object?> RunAsync(WorkflowActivityContext context, PaymentRequest req) | ||
{ | ||
LogPaymentProcessing(logger, req.RequestId, req.Amount, req.ItemBeingPurchased, req.Currency); | ||
|
||
public override async Task<object> RunAsync(WorkflowActivityContext context, PaymentRequest req) | ||
{ | ||
this.logger.LogInformation( | ||
"Processing payment: {requestId} for {amount} {item} at ${currency}", | ||
req.RequestId, | ||
req.Amount, | ||
req.ItemBeingPruchased, | ||
req.Currency); | ||
// Simulate slow processing | ||
await Task.Delay(TimeSpan.FromSeconds(7)); | ||
|
||
// Simulate slow processing | ||
await Task.Delay(TimeSpan.FromSeconds(7)); | ||
LogSuccessfulPayment(logger, req.RequestId); | ||
return null; | ||
} | ||
|
||
this.logger.LogInformation( | ||
"Payment for request ID '{requestId}' processed successfully", | ||
req.RequestId); | ||
[LoggerMessage(LogLevel.Information, "Processing payment: request ID '{requestId}' for {amount} {itemBeingPurchased} at ${currency}")] | ||
static partial void LogPaymentProcessing(ILogger logger, string requestId, int amount, string itemBeingPurchased, double currency); | ||
|
||
return null; | ||
} | ||
} | ||
} | ||
[LoggerMessage(LogLevel.Information, "Payment for request ID '{requestId}' processed successfully")] | ||
static partial void LogSuccessfulPayment(ILogger logger, string requestId); | ||
} |
97 changes: 45 additions & 52 deletions
97
workflows/csharp/sdk/order-processor/Activities/ReserveInventoryActivity.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,62 +1,55 @@ | ||
namespace WorkflowConsoleApp.Activities | ||
namespace WorkflowConsoleApp.Activities; | ||
|
||
using System.Threading.Tasks; | ||
using Dapr.Client; | ||
using Dapr.Workflow; | ||
using Microsoft.Extensions.Logging; | ||
using Models; | ||
using System; | ||
|
||
internal sealed partial class ReserveInventoryActivity(ILogger<ReserveInventoryActivity> logger, DaprClient daprClient) : WorkflowActivity<InventoryRequest, InventoryResult> | ||
{ | ||
using System.Threading.Tasks; | ||
using Dapr.Client; | ||
using Dapr.Workflow; | ||
using Microsoft.Extensions.Logging; | ||
using WorkflowConsoleApp.Models; | ||
using System; | ||
|
||
class ReserveInventoryActivity : WorkflowActivity<InventoryRequest, InventoryResult> | ||
private const string StoreName = "statestore"; | ||
|
||
public override async Task<InventoryResult> RunAsync(WorkflowActivityContext context, InventoryRequest req) | ||
{ | ||
readonly ILogger logger; | ||
readonly DaprClient client; | ||
static readonly string storeName = "statestore"; | ||
LogReserveInventory(logger, req.RequestId, req.Quantity, req.ItemName); | ||
|
||
public ReserveInventoryActivity(ILoggerFactory loggerFactory, DaprClient client) | ||
// Ensure that the store has items | ||
var (orderResult, _) = await daprClient.GetStateAndETagAsync<OrderPayload>(StoreName, req.ItemName); | ||
|
||
// Catch for the case where the statestore isn't setup | ||
if (orderResult is null) | ||
{ | ||
this.logger = loggerFactory.CreateLogger<ReserveInventoryActivity>(); | ||
this.client = client; | ||
// Not enough items. | ||
LogStateNotFound(logger, req.RequestId, req.ItemName); | ||
return new InventoryResult(false, null); | ||
} | ||
|
||
public override async Task<InventoryResult> RunAsync(WorkflowActivityContext context, InventoryRequest req) | ||
// See if there are enough items to purchase | ||
if (orderResult.Quantity >= req.Quantity) | ||
{ | ||
this.logger.LogInformation( | ||
"Reserving inventory for order {requestId} of {quantity} {name}", | ||
req.RequestId, | ||
req.Quantity, | ||
req.ItemName); | ||
|
||
OrderPayload orderResponse; | ||
string key; | ||
|
||
// Ensure that the store has items | ||
(orderResponse, key) = await client.GetStateAndETagAsync<OrderPayload>(storeName, req.ItemName); | ||
|
||
// Catch for the case where the statestore isn't setup | ||
if (orderResponse == null) | ||
{ | ||
// Not enough items. | ||
return new InventoryResult(false, orderResponse); | ||
} | ||
|
||
this.logger.LogInformation( | ||
"There are: {requestId}, {name} available for purchase", | ||
orderResponse.Quantity, | ||
orderResponse.Name); | ||
|
||
// See if there're enough items to purchase | ||
if (orderResponse.Quantity >= req.Quantity) | ||
{ | ||
// Simulate slow processing | ||
await Task.Delay(TimeSpan.FromSeconds(2)); | ||
|
||
return new InventoryResult(true, orderResponse); | ||
} | ||
|
||
// Not enough items. | ||
return new InventoryResult(false, orderResponse); | ||
// Simulate slow processing | ||
await Task.Delay(TimeSpan.FromSeconds(2)); | ||
|
||
LogSufficientInventory(logger, req.Quantity, req.ItemName); | ||
return new InventoryResult(true, orderResult); | ||
} | ||
|
||
// Not enough items. | ||
LogInsufficientInventory(logger, req.RequestId, req.ItemName); | ||
return new InventoryResult(false, orderResult); | ||
} | ||
} | ||
|
||
[LoggerMessage(LogLevel.Information, "Reserving inventory for order request ID '{requestId}' of {quantity} {name}")] | ||
static partial void LogReserveInventory(ILogger logger, string requestId, int quantity, string name); | ||
|
||
[LoggerMessage(LogLevel.Warning, "Unable to locate an order result for request ID '{requestId}' for the indicated item {itemName} in the state store")] | ||
static partial void LogStateNotFound(ILogger logger, string requestId, string itemName); | ||
|
||
[LoggerMessage(LogLevel.Information, "There are: {quantity} {name} available for purchase")] | ||
static partial void LogSufficientInventory(ILogger logger, int quantity, string name); | ||
|
||
[LoggerMessage(LogLevel.Warning, "There is insufficient inventory available for order request ID '{requestId}' for the item {itemName}")] | ||
static partial void LogInsufficientInventory(ILogger logger, string requestId, string itemName); | ||
} |
Oops, something went wrong.