|
| 1 | +package chasmtest |
| 2 | + |
| 3 | +import ( |
| 4 | + "context" |
| 5 | + "fmt" |
| 6 | + |
| 7 | + "go.temporal.io/server/chasm" |
| 8 | +) |
| 9 | + |
| 10 | +// ExecutePureTask validates and executes a pure task atomically via [Engine.UpdateComponent]. |
| 11 | +// It returns taskDropped set to true if [chasm.PureTaskHandler.Validate] returns (false, nil), |
| 12 | +// indicating the task is no longer relevant and was not executed. |
| 13 | +// |
| 14 | +// The component ref is resolved automatically — no separate [Engine.ReadComponent] call to |
| 15 | +// obtain a ref is needed. Pass the component pointer directly. |
| 16 | +// |
| 17 | +// This helper ensures that Validate is always exercised alongside Execute, matching the real |
| 18 | +// engine's behavior. Use [chasm.MockMutableContext] directly when you need to inspect the |
| 19 | +// typed task payloads added to the context during execution. |
| 20 | +func ExecutePureTask[C chasm.Component, T any]( |
| 21 | + ctx context.Context, |
| 22 | + e *Engine, |
| 23 | + component C, |
| 24 | + handler chasm.PureTaskHandler[C, T], |
| 25 | + attrs chasm.TaskAttributes, |
| 26 | + task T, |
| 27 | +) (taskDropped bool, err error) { |
| 28 | + ref, err := e.refForComponent(component) |
| 29 | + if err != nil { |
| 30 | + return false, err |
| 31 | + } |
| 32 | + |
| 33 | + engineCtx := chasm.NewEngineContext(ctx, e) |
| 34 | + _, err = e.UpdateComponent( |
| 35 | + engineCtx, |
| 36 | + ref, |
| 37 | + func(mutableCtx chasm.MutableContext, c chasm.Component) error { |
| 38 | + typedC, ok := c.(C) |
| 39 | + if !ok { |
| 40 | + return fmt.Errorf("component type mismatch: got %T", c) |
| 41 | + } |
| 42 | + var valid bool |
| 43 | + valid, err = handler.Validate(mutableCtx, typedC, attrs, task) |
| 44 | + if err != nil { |
| 45 | + return err |
| 46 | + } |
| 47 | + if !valid { |
| 48 | + taskDropped = true |
| 49 | + return nil |
| 50 | + } |
| 51 | + return handler.Execute(mutableCtx, typedC, attrs, task) |
| 52 | + }, |
| 53 | + ) |
| 54 | + return taskDropped, err |
| 55 | +} |
| 56 | + |
| 57 | +// ExecuteSideEffectTask validates and executes a side effect task. |
| 58 | +// Validation runs via [Engine.ReadComponent] in read only mode, and if valid, |
| 59 | +// [chasm.SideEffectTaskHandler.Execute] is called with an engine context so that |
| 60 | +// [chasm.UpdateComponent] and [chasm.ReadComponent] inside the handler route through |
| 61 | +// the test engine. |
| 62 | +// |
| 63 | +// It returns taskDropped set to true if [chasm.SideEffectTaskHandler.Validate] returns (false, nil), |
| 64 | +// indicating the task is no longer relevant and was not executed. |
| 65 | +// |
| 66 | +// The component ref is resolved automatically — no separate [Engine.ReadComponent] call to |
| 67 | +// obtain a ref is needed. Pass the component pointer directly. |
| 68 | +// |
| 69 | +// Use [chasm.MockMutableContext] directly when you need to inspect typed task payloads added |
| 70 | +// during execution, since the real engine serializes them into history layer tasks. |
| 71 | +func ExecuteSideEffectTask[C chasm.Component, T any]( |
| 72 | + ctx context.Context, |
| 73 | + e *Engine, |
| 74 | + component C, |
| 75 | + handler chasm.SideEffectTaskHandler[C, T], |
| 76 | + attrs chasm.TaskAttributes, |
| 77 | + task T, |
| 78 | +) (taskDropped bool, err error) { |
| 79 | + ref, err := e.refForComponent(component) |
| 80 | + if err != nil { |
| 81 | + return false, err |
| 82 | + } |
| 83 | + |
| 84 | + engineCtx := chasm.NewEngineContext(ctx, e) |
| 85 | + |
| 86 | + var valid bool |
| 87 | + if err = e.ReadComponent( |
| 88 | + engineCtx, |
| 89 | + ref, |
| 90 | + func(chasmCtx chasm.Context, c chasm.Component) error { |
| 91 | + typedC, ok := c.(C) |
| 92 | + if !ok { |
| 93 | + return fmt.Errorf("component type mismatch: got %T", c) |
| 94 | + } |
| 95 | + valid, err = handler.Validate(chasmCtx, typedC, attrs, task) |
| 96 | + return err |
| 97 | + }, |
| 98 | + ); err != nil { |
| 99 | + return false, err |
| 100 | + } |
| 101 | + if !valid { |
| 102 | + return true, nil |
| 103 | + } |
| 104 | + |
| 105 | + return false, handler.Execute(engineCtx, ref, attrs, task) |
| 106 | +} |
0 commit comments