-
Notifications
You must be signed in to change notification settings - Fork 726
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
[Workflow] Add examples for reuse ID policy #4237
Changes from 1 commit
fb3c1e0
2ca982b
f1ebce8
1761f30
8272c18
02087f2
ba2c043
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 |
---|---|---|
|
@@ -28,9 +28,117 @@ There are several different kinds of tasks that a workflow can schedule, includi | |
|
||
### Workflow identity | ||
|
||
Each workflow you define has a type name, and individual executions of a workflow require a unique _instance ID_. Workflow instance IDs can be generated by your app code, which is useful when workflows correspond to business entities like documents or jobs, or can be auto-generated UUIDs. A workflow's instance ID is useful for debugging and also for managing workflows using the [Workflow APIs]({{< ref workflow_api.md >}}). | ||
Each workflow you define has a type name, and individual executions of a workflow require a unique _instance ID_. Only one workflow instance with a given ID can exist at any given time. Workflow instance IDs can be generated by your app code, which is useful when workflows correspond to business entities like documents or jobs, or can be auto-generated UUIDs. A workflow's instance ID is useful for debugging and also for managing workflows using the [Workflow APIs]({{< ref workflow_api.md >}}). | ||
|
||
Only one workflow instance with a given ID can exist at any given time. However, if a workflow instance completes or fails, its ID can be reused by a new workflow instance. Note, however, that the new workflow instance effectively replaces the old one in the configured state store. | ||
#### Reusing workflow identities | ||
|
||
If a workflow instance completes or fails, its ID can be reused by a new workflow instance. The new workflow instance effectively replaces the old one in the configured state store. | ||
|
||
**Example 1** | ||
|
||
The following example demonstrates `main` executing a workflow twice. In the example: | ||
1. The workflow calls a single activity with orchestration ID reuse policy. | ||
1. The reuse ID policy specifies the action `IGNORE_IF_RUNNING_OR_COMPLETED` and the target statuses of `RUNNING`, `COMPLETED`, `PENDING`. | ||
1. The second call to create a workflow with the same instance ID is expected to be ignored if the first workflow instance is one of the target statuses. | ||
|
||
```go | ||
func main() { | ||
r := task.NewTaskRegistry() | ||
r.AddOrchestratorN("SingleActivity", func(ctx *task.OrchestrationContext) (any, error) { | ||
var input string | ||
if err := ctx.GetInput(&input); err != nil { | ||
return nil, err | ||
} | ||
var output string | ||
err := ctx.CallActivity("SayHello", task.WithActivityInput(input)).Await(&output) | ||
return output, err | ||
}) | ||
r.AddActivityN("SayHello", func(ctx task.ActivityContext) (any, error) { | ||
var name string | ||
if err := ctx.GetInput(&name); err != nil { | ||
return nil, err | ||
} | ||
return fmt.Sprintf("Hello, %s!", name), nil | ||
}) | ||
|
||
ctx := context.Background() | ||
client, engine := startEngine(ctx, r) | ||
|
||
instanceID := api.InstanceID("IGNORE_IF_RUNNING_OR_COMPLETED") | ||
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 string value here is intended to be the workflow ID, which is typically some business identity or is random (in which case we don't use it at all). It looks like we're trying to specify a policy as a workflow ID, which is a bit confusing. I think it would be better to not specify an explicit workflow ID at all to avoid confusion. 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. Given this code all need to change to workflow example, this can be changed at the same time. |
||
reuseIDPolicy := &api.OrchestrationIdReusePolicy{ | ||
Action: api.REUSE_ID_ACTION_IGNORE, | ||
OperationStatus: []api.OrchestrationStatus{api.RUNTIME_STATUS_RUNNING, api.RUNTIME_STATUS_COMPLETED, api.RUNTIME_STATUS_PENDING}, | ||
} | ||
|
||
// Run the orchestration | ||
id, err := client.ScheduleNewOrchestration(ctx, "SingleActivity", api.WithInput("World"), api.WithInstanceID(instanceID)) | ||
if err != nil { | ||
fmt.Println(err) | ||
return | ||
} | ||
// Wait for orchestration to start | ||
client.WaitForOrchestrationStart(ctx, id) | ||
// Schedule again, it should ignore creating the new orchestration | ||
hhunter-ms marked this conversation as resolved.
Show resolved
Hide resolved
|
||
id, err = client.ScheduleNewOrchestration(ctx, "SingleActivity", api.WithInput("World"), api.WithInstanceID(id), api.WithOrchestrationIdReusePolicy(reuseIDPolicy)) | ||
if err != nil { | ||
fmt.Println(err) | ||
return | ||
} | ||
} | ||
``` | ||
|
||
**Example 2** | ||
|
||
In the following example: | ||
1. The workflow calls a single activity with the orchestration ID reuse policy. | ||
1. The reuse ID policy contains the action to `TERMINATE` and target statuses `RUNNING`, `COMPLETED`, and `PENDING`. | ||
1. The second call to create a workflow with the same workflow instance ID is expected to terminate the first workflow instance and create a new workflow instance if in one of the target statuses. | ||
|
||
```go | ||
func main() { | ||
r := task.NewTaskRegistry() | ||
r.AddOrchestratorN("SingleActivity", func(ctx *task.OrchestrationContext) (any, error) { | ||
var input string | ||
if err := ctx.GetInput(&input); err != nil { | ||
return nil, err | ||
} | ||
var output string | ||
err := ctx.CallActivity("SayHello", task.WithActivityInput(input)).Await(&output) | ||
return output, err | ||
}) | ||
r.AddActivityN("SayHello", func(ctx task.ActivityContext) (any, error) { | ||
var name string | ||
if err := ctx.GetInput(&name); err != nil { | ||
return nil, err | ||
} | ||
return fmt.Sprintf("Hello, %s!", name), nil | ||
}) | ||
|
||
ctx := context.Background() | ||
client, engine := startEngine(ctx, r) | ||
|
||
instanceID := api.InstanceID("IGNORE_IF_RUNNING_OR_COMPLETED") | ||
reuseIDPolicy := &api.OrchestrationIdReusePolicy{ | ||
Action: api.REUSE_ID_ACTION_TERMINATE, | ||
OperationStatus: []api.OrchestrationStatus{api.RUNTIME_STATUS_RUNNING, api.RUNTIME_STATUS_COMPLETED, api.RUNTIME_STATUS_PENDING}, | ||
} | ||
|
||
// Run the orchestration | ||
id, err := client.ScheduleNewOrchestration(ctx, "SingleActivity", api.WithInput("World"), api.WithInstanceID(instanceID)) | ||
if err != nil { | ||
fmt.Println(err) | ||
return | ||
} | ||
// Wait for orchestration to start | ||
client.WaitForOrchestrationStart(ctx, id) | ||
// Schedule again, it should ignore creating the new orchestration | ||
hhunter-ms marked this conversation as resolved.
Show resolved
Hide resolved
|
||
id, err = client.ScheduleNewOrchestration(ctx, "SingleActivity", api.WithInput("World"), api.WithInstanceID(id), api.WithOrchestrationIdReusePolicy(reuseIDPolicy)) | ||
if err != nil { | ||
fmt.Println(err) | ||
return | ||
} | ||
} | ||
``` | ||
|
||
### Workflow replay | ||
|
||
|
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.
To be clear here, you can set a policy called "api.REUSE_ID_ACTION_TERMINATE" that does force an existing workflow to terminate so you can start a new workflow with the same id.
Is this correct? Little unclear here in the wording. If so, then it would also be good to have a list of the reuse ID policies somewhere in the docs.
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.
yes that's correct
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.
@kaibocai - Can you then provide a list of the api.REUSE_ID_ACTION_XX values and what each one does in a table?