|
| 1 | +# Child Workflow Sample |
| 2 | + |
| 3 | +This sample demonstrates **parent-child workflow relationships** and the **ContinueAsNew** pattern for long-running workflows. |
| 4 | + |
| 5 | +> **Looking for a visual guide?** See [new_samples/hello_world](../../../../new_samples/hello_world/) for a step-by-step tutorial with screenshots. |
| 6 | +
|
| 7 | +## How It Works |
| 8 | + |
| 9 | +``` |
| 10 | +┌─────────────────────────────────────────────────────┐ |
| 11 | +│ Parent Workflow │ |
| 12 | +│ ExecuteChildWorkflow(child, 0, 5) │ |
| 13 | +│ │ │ |
| 14 | +│ ▼ │ |
| 15 | +│ ┌─────────────────────────────────────────────┐ │ |
| 16 | +│ │ Child Workflow │ │ |
| 17 | +│ │ Run 1 → ContinueAsNew │ │ |
| 18 | +│ │ Run 2 → ContinueAsNew │ │ |
| 19 | +│ │ Run 3 → ContinueAsNew │ │ |
| 20 | +│ │ Run 4 → ContinueAsNew │ │ |
| 21 | +│ │ Run 5 → Complete ✓ │ │ |
| 22 | +│ └─────────────────────────────────────────────┘ │ |
| 23 | +│ │ │ |
| 24 | +│ ▼ │ |
| 25 | +│ Parent receives: "completed after 5 runs" │ |
| 26 | +└─────────────────────────────────────────────────────┘ |
| 27 | +``` |
| 28 | + |
| 29 | +**Use cases:** |
| 30 | +- Breaking large workflows into modular pieces |
| 31 | +- Long-running workflows that need to reset history (ContinueAsNew) |
| 32 | +- Workflow decomposition for better organization |
| 33 | + |
| 34 | +## Prerequisites |
| 35 | + |
| 36 | +1. Cadence server running (see [main README](../../../../README.md)) |
| 37 | +2. Build the samples: `make` |
| 38 | + |
| 39 | +## Running the Sample |
| 40 | + |
| 41 | +```bash |
| 42 | +# Terminal 1: Start worker |
| 43 | +./bin/childworkflow -m worker |
| 44 | + |
| 45 | +# Terminal 2: Trigger workflow |
| 46 | +./bin/childworkflow -m trigger |
| 47 | +``` |
| 48 | + |
| 49 | +## Key Code |
| 50 | + |
| 51 | +### Parent Workflow |
| 52 | +```go |
| 53 | +cwo := workflow.ChildWorkflowOptions{ |
| 54 | + WorkflowID: childID, |
| 55 | + ExecutionStartToCloseTimeout: time.Minute, |
| 56 | +} |
| 57 | +ctx = workflow.WithChildOptions(ctx, cwo) |
| 58 | + |
| 59 | +var result string |
| 60 | +err := workflow.ExecuteChildWorkflow(ctx, sampleChildWorkflow, 0, 5).Get(ctx, &result) |
| 61 | +``` |
| 62 | + |
| 63 | +### Child Workflow with ContinueAsNew |
| 64 | +```go |
| 65 | +func sampleChildWorkflow(ctx workflow.Context, totalCount, runCount int) (string, error) { |
| 66 | + totalCount++ |
| 67 | + runCount-- |
| 68 | + |
| 69 | + if runCount == 0 { |
| 70 | + return fmt.Sprintf("completed after %v runs", totalCount), nil |
| 71 | + } |
| 72 | + |
| 73 | + // Restart workflow with new parameters (resets history) |
| 74 | + return "", workflow.NewContinueAsNewError(ctx, sampleChildWorkflow, totalCount, runCount) |
| 75 | +} |
| 76 | +``` |
| 77 | + |
| 78 | +## Why ContinueAsNew? |
| 79 | + |
| 80 | +Workflow history grows with each event. For long-running workflows, use `ContinueAsNew` to: |
| 81 | +- Reset the history size |
| 82 | +- Prevent hitting history limits |
| 83 | +- Keep workflows performant |
| 84 | + |
| 85 | +## References |
| 86 | + |
| 87 | +- [Child Workflows](https://cadenceworkflow.io/docs/go-client/child-workflows/) |
| 88 | +- [ContinueAsNew](https://cadenceworkflow.io/docs/go-client/continue-as-new/) |
| 89 | + |
0 commit comments