Merge branch 'v1.11' into issue_3216

This commit is contained in:
Mark Fussell 2023-05-31 19:17:48 -07:00 committed by GitHub
commit 4b0a175549
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 107 additions and 2 deletions

View File

@ -264,6 +264,96 @@ A workflow implementing the monitor pattern can loop forever or it can terminate
This pattern can also be expressed using actors and reminders. The difference is that this workflow is expressed as a single function with inputs and state stored in local variables. Workflows can also execute a sequence of actions with stronger reliability guarantees, if necessary.
{{% /alert %}}
## External system interaction
In some cases, a workflow may need to pause and wait for an external system to perform some action. For example, a workflow may need to pause and wait for a payment to be received. In this case, a payment system might publish an event to a pub/sub topic on receipt of a payment, and a listener on that topic can raise an event to the workflow using the [raise event workflow API]({{< ref "howto-manage-workflow.md#raise-an-event" >}}).
Another very common scenario is when a workflow needs to pause and wait for a human, for example when approving a purchase order. Dapr Workflow supports this event pattern via the [external events]({{< ref "workflow-features-concepts.md#external-events" >}}) feature.
Here's an example workflow for a purchase order involving a human:
1. A workflow is triggered when a purchase order is received.
1. A rule in the workflow determines that a human needs to perform some action. For example, the purchase order cost exceeds a certain auto-approval threshold.
1. The workflow sends a notification requesting a human action. For example, it sends an email with an approval link to a designated approver.
1. The workflow pauses and waits for the human to either approve or reject the order by clicking on a link.
1. If the approval isn't received within the specified time, the workflow resumes and performs some compensation logic, such as canceling the order.
The following diagram illustrates this flow.
<img src="/images/workflow-overview/workflow-human-interaction-pattern.png" width=600 alt="Diagram showing how the external system interaction pattern works with a human involved"/>
The following example code shows how this pattern can be implemented using Dapr Workflow.
{{< tabs ".NET" >}}
{{% codetab %}}
```csharp
public override async Task<OrderResult> RunAsync(WorkflowContext context, OrderPayload order)
{
// ...(other steps)...
// Require orders over a certain threshold to be approved
if (order.TotalCost > OrderApprovalThreshold)
{
try
{
// Request human approval for this order
await context.CallActivityAsync(nameof(RequestApprovalActivity), order);
// Pause and wait for a human to approve the order
ApprovalResult approvalResult = await context.WaitForExternalEventAsync<ApprovalResult>(
eventName: "ManagerApproval",
timeout: TimeSpan.FromDays(3));
if (approvalResult == ApprovalResult.Rejected)
{
// The order was rejected, end the workflow here
return new OrderResult(Processed: false);
}
}
catch (TaskCanceledException)
{
// An approval timeout results in automatic order cancellation
return new OrderResult(Processed: false);
}
}
// ...(other steps)...
// End the workflow with a success result
return new OrderResult(Processed: true);
}
```
{{% alert title="Note" color="primary" %}}
In the example above, `RequestApprovalActivity` is the name of a workflow activity to invoke and `ApprovalResult` is an enumeration defined by the workflow app. For brevity, these definitions were left out of the example code.
{{% /alert %}}
{{% /codetab %}}
{{< /tabs >}}
The code that delivers the event to resume the workflow execution is external to the workflow. Workflow events can be delivered to a waiting workflow instance using the [raise event]({{< ref "howto-manage-workflow.md#raise-an-event" >}}) workflow management API, as shown in the following example:
{{< tabs ".NET" >}}
{{% codetab %}}
```csharp
// Raise the workflow event to the waiting workflow
await daprClient.RaiseWorkflowEventAsync(
instanceId: orderId,
workflowComponent: "dapr",
eventName: "ManagerApproval",
eventData: ApprovalResult.Approved);
```
{{% /codetab %}}
{{< /tabs >}}
External events don't have to be directly triggered by humans. They can also be triggered by other systems. For example, a workflow may need to pause and wait for a payment to be received. In this case, a payment system might publish an event to a pub/sub topic on receipt of a payment, and a listener on that topic can raise an event to the workflow using the raise event workflow API.
## Next steps
{{< button text="Workflow architecture >>" page="workflow-architecture.md" >}}

View File

@ -67,6 +67,14 @@ You can also name each app directory's `.dapr` directory something other than `.
## Logs
The run template provides two log destination fields for each application and its associated daprd process:
1. `appLogDestination` : This field configures the log destination for the application. The possible values are `console`, `file` and `fileAndConsole`. The default value is `fileAndConsole` where application logs are written to both console and to a file by default.
2. `daprdLogDestination` : This field configures the log destination for the `daprd` process. The possible values are `console`, `file` and `fileAndConsole`. The default value is `file` where the `daprd` logs are written to a file by default.
#### Log file format
Logs for application and `daprd` are captured in separate files. These log files are created automatically under `.dapr/logs` directory under each application directory (`appDirPath` in the template). These log file names follow the pattern seen below:
- `<appID>_app_<timestamp>.log` (file name format for `app` log)
@ -74,6 +82,7 @@ Logs for application and `daprd` are captured in separate files. These log files
Even if you've decided to rename your resources folder to something other than `.dapr`, the log files are written only to the `.dapr/logs` folder (created in the application directory).
## Watch the demo
Watch [this video for an overview on Multi-App Run](https://youtu.be/s1p9MNl4VGo?t=2456):

View File

@ -76,12 +76,15 @@ common: # optional section for variables shared across apps
apps:
- appID: webapp # optional
appDirPath: .dapr/webapp/ # REQUIRED
resourcesPath: .dapr/resources # (optional) can be default by convention
resourcesPath: .dapr/resources # deprecated
resourcesPaths: .dapr/resources # comman separated resources paths. (optional) can be default by convention
configFilePath: .dapr/config.yaml # (optional) can be default by convention too, ignore if file is not found.
appProtocol: http
appPort: 8080
appHealthCheckPath: "/healthz"
command: ["python3" "app.py"]
appLogDestination: file # (optional), can be file, console or fileAndConsole. default is fileAndConsole.
daprdLogDestination: file # (optional), can be file, console or fileAndConsole. default is file.
- appID: backend # optional
appDirPath: .dapr/backend/ # REQUIRED
appProtocol: grpc
@ -110,7 +113,8 @@ The properties for the Multi-App Run template align with the `dapr run` CLI flag
|--------------------------|:--------:|--------|---------|
| `appDirPath` | Y | Path to the your application code | `./webapp/`, `./backend/` |
| `appID` | N | Application's app ID. If not provided, will be derived from `appDirPath` | `webapp`, `backend` |
| `resourcesPath` | N | Path to your Dapr resources. Can be default by convention; ignore if directory isn't found | `./app/components`, `./webapp/components` |
| `resourcesPath` | N | **Deprecated**. Path to your Dapr resources. Can be default by convention| `./app/components`, `./webapp/components` |
| `resourcesPaths` | N | Comma separated paths to your Dapr resources. Can be default by convention | `./app/components`, `./webapp/components` |
| `configFilePath` | N | Path to your application's configuration file | `./webapp/config.yaml` |
| `appProtocol` | N | The protocol Dapr uses to talk to the application. | `http`, `grpc` |
| `appPort` | N | The port your application is listening on | `8080`, `3000` |
@ -137,6 +141,8 @@ The properties for the Multi-App Run template align with the `dapr run` CLI flag
| `enableApiLogging` | N | Enable the logging of all API calls from application to Dapr | |
| `runtimePath` | N | Dapr runtime install path | |
| `env` | N | Map to environment variable; environment variables applied per application will overwrite environment variables shared across applications | `DEBUG`, `DAPR_HOST_ADD` |
| `appLogDestination` | N | Log destination for outputting app logs; Its value can be file, console or fileAndConsole. Default is fileAndConsole | `file`, `console`, `fileAndConsole` |
| `daprdLogDestination` | N | Log destination for outputting daprd logs; Its value can be file, console or fileAndConsole. Default is file | `file`, `console`, `fileAndConsole` |
## Next steps

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB