|
45 | 45 | // Version represents a change version. See GetVersion call. |
46 | 46 | Version = internal.Version |
47 | 47 |
|
| 48 | + // GetVersionOption configures GetVersion behaviour |
| 49 | + GetVersionOption = internal.GetVersionOption |
| 50 | + |
48 | 51 | // ChildWorkflowOptions stores all child workflow specific parameters that will be stored inside of a Context. |
49 | 52 | ChildWorkflowOptions = internal.ChildWorkflowOptions |
50 | 53 |
|
@@ -353,6 +356,77 @@ func MutableSideEffect(ctx Context, id string, f func(ctx Context) interface{}, |
353 | 356 | // DefaultVersion is a version returned by GetVersion for code that wasn't versioned before |
354 | 357 | const DefaultVersion Version = internal.DefaultVersion |
355 | 358 |
|
| 359 | +// ExecuteWithVersion returns a GetVersionOption that forces a specific version to be returned |
| 360 | +// when executed for the first time, instead of returning maxSupported version. |
| 361 | +// |
| 362 | +// This option can be used when you want to separate the versioning of the workflow code and |
| 363 | +// activation of the new logic in the workflow code, to ensure that your changes can be safely rolled back |
| 364 | +// if needed. For example, initially a workflow has the following code: |
| 365 | +// |
| 366 | +// err = workflow.ExecuteActivity(ctx, foo).Get(ctx, nil) |
| 367 | +// |
| 368 | +// It should be updated to: |
| 369 | +// |
| 370 | +// err = workflow.ExecuteActivity(ctx, bar).Get(ctx, nil) |
| 371 | +// |
| 372 | +// Step 1 |
| 373 | +// To roll out your changes safely, both versions of your workflow code should be compatible with each other. |
| 374 | +// To achieve that, you can use GetVersion with ExecuteWithVersion option. |
| 375 | +// When GetVersion is executed for the first time, it will return DefaultVersion instead of maxSupported version: |
| 376 | +// |
| 377 | +// v := GetVersion(ctx, "fooChange", DefaultVersion, 1, ExecuteWithVersion(DefaultVersion)) |
| 378 | +// if v == DefaultVersion { |
| 379 | +// err = workflow.ExecuteActivity(ctx, foo).Get(ctx, nil) |
| 380 | +// } else { |
| 381 | +// err = workflow.ExecuteActivity(ctx, bar).Get(ctx, nil) |
| 382 | +// } |
| 383 | +// |
| 384 | +// At this step, the previous version of the code supports only DefaultVersion, however new version of the code |
| 385 | +// supports both DefaultVersion and 1. At the same time, the new version of the code is not yet activated, |
| 386 | +// so the workflow started on the new version of the code will still execute foo activity - previous version of the code. |
| 387 | +// This makes it possible to safely roll back your changes if needed, as the previous code supports DefaultVersion. |
| 388 | +// |
| 389 | +// Step 2 |
| 390 | +// When the previous version of the code is no longer running, there is no need to start new workflow executions |
| 391 | +// with DefaultVersion anymore, and you can the maxSupported version to activate the new code. To achieve that you can |
| 392 | +// remove the usage of ExecuteWithVersion option. When GetVersion is executed for the first time, it will return maxSupported version: |
| 393 | +// |
| 394 | +// v := GetVersion(ctx, "fooChange", DefaultVersion, 1) |
| 395 | +// if v == DefaultVersion { |
| 396 | +// err = workflow.ExecuteActivity(ctx, foo).Get(ctx, nil) |
| 397 | +// } else { |
| 398 | +// err = workflow.ExecuteActivity(ctx, bar).Get(ctx, nil) |
| 399 | +// } |
| 400 | +// |
| 401 | +// At this step, the previous and old versions of the code support both versions DefaultVersion and 1, |
| 402 | +// however the new version of the code is activated, so the workflow started on the new version of the code |
| 403 | +// will execute bar activity - new version of the code. This makes it possible to safely roll back your changes if needed, |
| 404 | +// because both versions of the code support both versions DefaultVersion and 1. |
| 405 | +// |
| 406 | +// Step 3 |
| 407 | +// When there are no running previous version of the code and there are no workflow executions |
| 408 | +// running DefaultVersion the correspondent branch can be removed: |
| 409 | +// |
| 410 | +// GetVersion(ctx, "fooChange", 1, 1) |
| 411 | +// err = workflow.ExecuteActivity(ctx, bar).Get(ctx, nil) |
| 412 | +// |
| 413 | +// ExecuteWithVersion option is useful when you want to ensure that your changes can be safely rolled back if needed, as |
| 414 | +// both versions of the workflow code are compatible with each other. |
| 415 | +func ExecuteWithVersion(version Version) GetVersionOption { |
| 416 | + return func(o *internal.GetVersionOptions) { |
| 417 | + o.CustomVersion = &version |
| 418 | + } |
| 419 | +} |
| 420 | + |
| 421 | +// ExecuteWithMinVersion returns a GetVersionOption that makes GetVersion return minSupported version |
| 422 | +// when executed for the first time, instead of returning maxSupported version. |
| 423 | +// To see how this option can be used, see the ExecuteWithVersion option |
| 424 | +func ExecuteWithMinVersion() GetVersionOption { |
| 425 | + return func(o *internal.GetVersionOptions) { |
| 426 | + o.UseMinVersion = true |
| 427 | + } |
| 428 | +} |
| 429 | + |
356 | 430 | // GetVersion is used to safely perform backwards incompatible changes to workflow definitions. |
357 | 431 | // It is not allowed to update workflow code while there are workflows running as it is going to break |
358 | 432 | // determinism. The solution is to have both old code that is used to replay existing workflows |
@@ -418,8 +492,8 @@ const DefaultVersion Version = internal.DefaultVersion |
418 | 492 | // } else { |
419 | 493 | // err = workflow.ExecuteActivity(ctx, qux, data).Get(ctx, nil) |
420 | 494 | // } |
421 | | -func GetVersion(ctx Context, changeID string, minSupported, maxSupported Version) Version { |
422 | | - return internal.GetVersion(ctx, changeID, minSupported, maxSupported) |
| 495 | +func GetVersion(ctx Context, changeID string, minSupported, maxSupported Version, opts ...GetVersionOption) Version { |
| 496 | + return internal.GetVersion(ctx, changeID, minSupported, maxSupported, opts...) |
423 | 497 | } |
424 | 498 |
|
425 | 499 | // SetQueryHandler sets the query handler to handle workflow query. The queryType specify which query type this handler |
|
0 commit comments