From 9c3516f90f8d49e82e03d303ca7b834807caa256 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 7 Sep 2026 11:07:10 -0700 Subject: [PATCH 01/18] Add Nexus workflow messaging actions --- internal/workertest/historyrequire.go | 13 + loadgen/kitchen_sink_executor_test.go | 124 +++- loadgen/kitchensink/helpers.go | 106 ++- loadgen/kitchensink/kitchen_sink.pb.go | 102 ++- .../Temporalio.Omes/protos/KitchenSink.cs | 161 ++++- .../go/workerlib/kitchensink/kitchen_sink.go | 155 +++- .../java/io/temporal/omes/KitchenSink.java | 675 +++++++++++++++++- workers/proto/kitchen_sink/kitchen_sink.proto | 8 + workers/python/protos/kitchen_sink_pb2.py | 28 +- workers/python/protos/kitchen_sink_pb2.pyi | 8 +- workers/ruby/protos/kitchen_sink_pb.rb | 2 +- 11 files changed, 1255 insertions(+), 127 deletions(-) diff --git a/internal/workertest/historyrequire.go b/internal/workertest/historyrequire.go index a093358d..4709adde 100644 --- a/internal/workertest/historyrequire.go +++ b/internal/workertest/historyrequire.go @@ -278,6 +278,19 @@ func looselyEqual(x, y any) bool { return mapIsSuperset(x, yMap) } return false + case []any: + // Compare element-wise so each expected element can be a partial map. The + // lengths must match, but not every field of each element. + yList, ok := y.([]any) + if !ok || len(yList) != len(x) { + return false + } + for i, yv := range yList { + if !looselyEqual(x[i], yv) { + return false + } + } + return true } return reflect.DeepEqual(x, y) } diff --git a/loadgen/kitchen_sink_executor_test.go b/loadgen/kitchen_sink_executor_test.go index 4c9a6041..e8266eeb 100644 --- a/loadgen/kitchen_sink_executor_test.go +++ b/loadgen/kitchen_sink_executor_test.go @@ -9,6 +9,7 @@ import ( "testing" "time" + "github.com/google/uuid" "github.com/stretchr/testify/require" "github.com/temporalio/omes/clioptions" . "github.com/temporalio/omes/internal/workertest" @@ -43,6 +44,14 @@ var ( clioptions.LangDotNet: "executenexusoperation is not supported", } + nexusWorkflowActionUnsupportedSDKs = map[clioptions.Language]string{ + clioptions.LangPython: "no supported action set", + clioptions.LangJava: "executenexusoperation is not supported", + clioptions.LangRuby: "executenexusoperation is not supported", + clioptions.LangTypeScript: "executenexusoperation is not supported", + clioptions.LangDotNet: "executenexusoperation is not supported", + } + standaloneNexusUnsupportedSDKs = map[clioptions.Language]string{ clioptions.LangJava: "dostandalonenexusoperation is not supported", clioptions.LangPython: "dostandalonenexusoperation is not supported", @@ -94,6 +103,8 @@ func TestKitchenSink(t *testing.T) { "nexusoperation.enableStandalone": true, // Standalone Nexus system callbacks require CHASM callbacks. "history.enableCHASMCallbacks": true, + // Nexus Signals rely on CHASM signal backlinks. + "history.enableCHASMSignalBacklinks": true, // Enable StartActivityExecution for the standalone-activity subtest. "activity.enableStandalone": true, "history.enableStandaloneActivityOperatorCommands": true, @@ -937,7 +948,7 @@ func TestKitchenSink(t *testing.T) { WorkflowExecutionCompleted`), }, { - name: "NexusOperation/Sync", + name: "NexusOperation/Sync/Echo", testInput: &TestInput{ WorkflowInput: &WorkflowInput{ InitialActions: ListActionSet( @@ -1202,6 +1213,58 @@ func TestKitchenSink(t *testing.T) { DoStandaloneActivityOperatorCommands_COMMAND_TYPE_RESET), standaloneActivityOperatorCommandsTestCase("Update", DoStandaloneActivityOperatorCommands_COMMAND_TYPE_UPDATE), + { + name: "NexusOperation/Sync/Signal", + testInput: &TestInput{WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( + NewNexusWorkflowTargetSequence("", "nexus-signal-target", nil, + NewNexusOperationAction("", + NexusSignalWorkflowRequest("nexus-signal-target", "", &DoSignal{}, nil), + ConvertToPayload("nexus-signal-target"), + WaitFinishChoice(), + ), + ), + )}}, + historyMatcher: PartialHistoryMatcher(` + NexusOperationCompleted {"links":[{"workflowEvent":{"workflowId":"nexus-signal-target","requestIdRef":{"eventType":"EVENT_TYPE_WORKFLOW_EXECUTION_SIGNALED"}}}]}`), + expectedUnsupportedErrs: nexusWorkflowActionUnsupportedSDKs, + }, + { + name: "NexusOperation/Sync/SignalWithStart", + testInput: &TestInput{WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( + NewNexusWorkflowTargetSequence("", "nexus-sws-target", + NewNexusOperationAction("", + NexusSignalWorkflowRequest("nexus-sws-target", "", &DoSignal{WithStart: true}, + &NexusWorkflowStartOptions{WorkflowInput: &WorkflowInput{}}), + ConvertToPayload("nexus-sws-target"), + WaitFinishChoice(), + ), + ), + )}}, + historyMatcher: PartialHistoryMatcher(` + NexusOperationCompleted {"links":[{"workflowEvent":{"workflowId":"nexus-sws-target","requestIdRef":{"eventType":"EVENT_TYPE_WORKFLOW_EXECUTION_SIGNALED"}}}]}`), + expectedUnsupportedErrs: nexusWorkflowActionUnsupportedSDKs, + }, + { + name: "NexusOperation/Async/Update", + testInput: &TestInput{WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( + NewNexusWorkflowTargetSequence("", "nexus-update-target", nil, + NewNexusOperationAction("", + NexusUpdateWorkflowRequest("nexus-update-target", "", &DoUpdate{ + Variant: &DoUpdate_DoActions{DoActions: &DoActionsUpdate{ + Variant: &DoActionsUpdate_DoActions{DoActions: SingleActionSet( + NewNexusUpdateResultAction("nexus-update-target"), + )}, + }}, + }), + ConvertToPayload("nexus-update-target"), + WaitFinishChoice(), + ), + ), + )}}, + historyMatcher: PartialHistoryMatcher(` + NexusOperationCompleted {"links":[{"workflowEvent":{"workflowId":"nexus-update-target","requestIdRef":{"eventType":"EVENT_TYPE_WORKFLOW_EXECUTION_UPDATE_ACCEPTED"}}}]}`), + expectedUnsupportedErrs: nexusWorkflowActionUnsupportedSDKs, + }, { name: "UnsupportedAction", testInput: &TestInput{ @@ -1299,6 +1362,7 @@ func testForSDK( scenarioInfo := ScenarioInfo{ ScenarioName: "kitchenSinkTest", RunID: fmt.Sprintf("%s-%d", strings.ReplaceAll(t.Name(), "/", "-"), time.Now().Unix()), + ExecutionID: uuid.NewString(), Configuration: RunConfiguration{ Iterations: 1, }, @@ -1319,30 +1383,37 @@ func testForSDK( executor := &KitchenSinkExecutor{ TestInput: testInput, PrepareTestInput: func(_ context.Context, _ ScenarioInfo, input *TestInput) error { - if input.WorkflowInput != nil { - for _, actionSet := range input.WorkflowInput.InitialActions { - for _, action := range actionSet.Actions { - if nexusOp := action.GetNexusOperation(); nexusOp != nil && nexusOp.Endpoint == "" { - nexusOp.Endpoint = nexusEndpoint - } - if clientSeq := action.GetExecActivity().GetClient().GetClientSequence(); clientSeq != nil { - for _, cas := range clientSeq.ActionSets { - for _, ca := range cas.Actions { - if sno := ca.GetDoStandaloneNexusOperation().GetOperation(); sno != nil && sno.Endpoint == "" { - sno.Endpoint = nexusEndpoint - } - if sa := ca.GetDoStandaloneActivity(); sa.GetActivity() != nil && sa.GetActivity().TaskQueue == "" { - sa.GetActivity().TaskQueue = runTaskQueue - } - if op := ca.GetDoStandaloneActivityOperatorCommands(); op.GetActivity() != nil && op.GetActivity().TaskQueue == "" { - op.GetActivity().TaskQueue = runTaskQueue - } + var prepareActions func([]*Action) + prepareActions = func(actions []*Action) { + for _, action := range actions { + if nexusOp := action.GetNexusOperation(); nexusOp != nil && nexusOp.Endpoint == "" { + nexusOp.Endpoint = nexusEndpoint + } + if nested := action.GetNestedActionSet(); nested != nil { + prepareActions(nested.GetActions()) + } + if clientSeq := action.GetExecActivity().GetClient().GetClientSequence(); clientSeq != nil { + for _, cas := range clientSeq.ActionSets { + for _, ca := range cas.Actions { + if sno := ca.GetDoStandaloneNexusOperation().GetOperation(); sno != nil && sno.Endpoint == "" { + sno.Endpoint = nexusEndpoint + } + if sa := ca.GetDoStandaloneActivity(); sa.GetActivity() != nil && sa.GetActivity().TaskQueue == "" { + sa.GetActivity().TaskQueue = runTaskQueue + } + if op := ca.GetDoStandaloneActivityOperatorCommands(); op.GetActivity() != nil && op.GetActivity().TaskQueue == "" { + op.GetActivity().TaskQueue = runTaskQueue } } } } } } + if input.WorkflowInput != nil { + for _, actionSet := range input.WorkflowInput.InitialActions { + prepareActions(actionSet.Actions) + } + } return nil }, UpdateWorkflowOptions: func(_ context.Context, _ *Run, opts *KitchenSinkWorkflowOptions) error { @@ -1394,7 +1465,8 @@ func testSupportedFeature( _, execErr := env.RunExecutorTest(t, testExecutor, scenarioInfo, sdk) taskQueueName := TaskQueueForRun(scenarioInfo.RunID) - historyEvents, historyErr := getWorkflowHistory(t, env.TemporalClient(), env.Namespace(), taskQueueName) + historyEvents, historyErr := getWorkflowHistory( + t, env.TemporalClient(), env.Namespace(), taskQueueName, scenarioInfo.ExecutionID) if execErr != nil { if len(historyEvents) > 0 { t.Logf("History events for debugging:") @@ -1436,11 +1508,19 @@ func (w *kitchenSinkTestWrapper) Run(ctx context.Context, info ScenarioInfo) err return w.executor.Run(ctx, info) } -func getWorkflowHistory(t *testing.T, temporalClient client.Client, namespace, taskQueueName string) ([]*history.HistoryEvent, error) { +func getWorkflowHistory( + t *testing.T, + temporalClient client.Client, + namespace string, + taskQueueName string, + executionID string, +) ([]*history.HistoryEvent, error) { executions, err := temporalClient.ListWorkflow(t.Context(), &workflowservice.ListWorkflowExecutionsRequest{ Namespace: namespace, - Query: fmt.Sprintf("TaskQueue = '%s' AND WorkflowType = 'kitchenSink'", taskQueueName), + Query: fmt.Sprintf( + "TaskQueue = '%s' AND WorkflowType = 'kitchenSink' AND %s = '%s'", + taskQueueName, OmesExecutionIDSearchAttribute, executionID), }) if err != nil { return nil, fmt.Errorf("failed to list workflow executions: %w", err) diff --git a/loadgen/kitchensink/helpers.go b/loadgen/kitchensink/helpers.go index b91bb524..101c9935 100644 --- a/loadgen/kitchensink/helpers.go +++ b/loadgen/kitchensink/helpers.go @@ -96,6 +96,106 @@ func ClientActions(clientActions ...*ClientAction) *ClientSequence { } } +func NexusSignalWorkflowRequest( + workflowID string, + runID string, + signal *DoSignal, + options *NexusWorkflowStartOptions, +) *NexusOperationRequest { + return &NexusOperationRequest{ + Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ + WorkflowId: workflowID, + RunId: runID, + StartOptions: options, + Action: &NexusWorkflowAction_Signal{Signal: signal}, + }}, + } +} + +func NexusUpdateWorkflowRequest(workflowID string, runID string, update *DoUpdate) *NexusOperationRequest { + return &NexusOperationRequest{ + Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ + WorkflowId: workflowID, + RunId: runID, + Action: &NexusWorkflowAction_Update{Update: update}, + }}, + } +} + +// NewNexusUpdateResultAction returns a Payload as the workflow update result. +// The update handler's return value is itself encoded by the data converter +// before the server forwards it to the Nexus completion callback, so the value +// is wrapped twice here: the caller decodes the outer layer and compares the +// inner Payload against ExecuteNexusOperation.expected_output. +func NewNexusUpdateResultAction(value any) *Action { + return NewReturnResultAction(ConvertToPayload(ConvertToPayload(value))) +} + +func NewNexusOperationAction( + endpoint string, + input *NexusOperationRequest, + expectedOutput *common.Payload, + awaitableChoice *AwaitableChoice, +) *Action { + return &Action{ + Variant: &Action_NexusOperation{NexusOperation: &ExecuteNexusOperation{ + Endpoint: endpoint, + Operation: KitchenSinkNexusOperationName, + ExpectedOutput: expectedOutput, + AwaitableChoice: awaitableChoice, + Input: input, + }}, + } +} + +// NewNexusWorkflowTargetSequence starts one kitchenSink workflow, applies the +// provided actions to it, then completes the target and awaits pending actions. +func NewNexusWorkflowTargetSequence(endpoint string, workflowID string, startAction *Action, actions ...*Action) *Action { + if startAction == nil { + startAction = NewNexusOperationAction(endpoint, + &NexusOperationRequest{ + Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ + WorkflowId: workflowID, + StartOptions: &NexusWorkflowStartOptions{ + WorkflowInput: &WorkflowInput{}, + }, + Action: &NexusWorkflowAction_Start{Start: &emptypb.Empty{}}, + }}, + }, + nil, + &AwaitableChoice{Condition: &AwaitableChoice_WaitStarted{WaitStarted: &emptypb.Empty{}}}, + ) + } + sequence := make([]*Action, 0, len(actions)+3) + sequence = append(sequence, startAction) + sequence = append(sequence, actions...) + sequence = append(sequence, + &Action{Variant: &Action_SendSignal{SendSignal: &SendSignalAction{ + WorkflowId: workflowID, + SignalName: "do_actions_signal", + Args: []*common.Payload{ConvertToPayload(NewReturnResultSignal())}, + AwaitableChoice: WaitFinishChoice(), + }}}, + &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}, + ) + return &Action{Variant: &Action_NestedActionSet{NestedActionSet: &ActionSet{Actions: sequence}}} +} + +// WaitFinishChoice awaits an operation through to completion. +func WaitFinishChoice() *AwaitableChoice { + return &AwaitableChoice{ + Condition: &AwaitableChoice_WaitFinish{WaitFinish: &emptypb.Empty{}}, + } +} + +// NewReturnResultSignal completes a kitchenSink workflow through do_actions_signal. +func NewReturnResultSignal() *DoSignal_DoSignalActions { + return &DoSignal_DoSignalActions{ + Variant: &DoSignal_DoSignalActions_DoActionsInMain{ + DoActionsInMain: SingleActionSet(NewEmptyReturnResultAction()), + }, + } +} func ClientActivity(clientSeq *ClientSequence, factory ActionFactory[ExecuteActivityAction]) *Action { activity := &ExecuteActivityAction{ ActivityType: &ExecuteActivityAction_Client{ @@ -152,10 +252,14 @@ func ResourceConsumingActivity(bytesToAllocate uint64, cpuYieldEveryNIters uint3 } func NewEmptyReturnResultAction() *Action { + return NewReturnResultAction(&common.Payload{}) +} + +func NewReturnResultAction(payload *common.Payload) *Action { return &Action{ Variant: &Action_ReturnResult{ ReturnResult: &ReturnResultAction{ - ReturnThis: &common.Payload{}, + ReturnThis: payload, }, }, } diff --git a/loadgen/kitchensink/kitchen_sink.pb.go b/loadgen/kitchensink/kitchen_sink.pb.go index 02841f97..db52261e 100644 --- a/loadgen/kitchensink/kitchen_sink.pb.go +++ b/loadgen/kitchensink/kitchen_sink.pb.go @@ -3420,6 +3420,8 @@ type NexusWorkflowAction struct { // Types that are assignable to Action: // // *NexusWorkflowAction_Start + // *NexusWorkflowAction_Signal + // *NexusWorkflowAction_Update Action isNexusWorkflowAction_Action `protobuf_oneof:"action"` } @@ -3490,6 +3492,20 @@ func (x *NexusWorkflowAction) GetStart() *emptypb.Empty { return nil } +func (x *NexusWorkflowAction) GetSignal() *DoSignal { + if x, ok := x.GetAction().(*NexusWorkflowAction_Signal); ok { + return x.Signal + } + return nil +} + +func (x *NexusWorkflowAction) GetUpdate() *DoUpdate { + if x, ok := x.GetAction().(*NexusWorkflowAction_Update); ok { + return x.Update + } + return nil +} + type isNexusWorkflowAction_Action interface { isNexusWorkflowAction_Action() } @@ -3498,8 +3514,26 @@ type NexusWorkflowAction_Start struct { Start *emptypb.Empty `protobuf:"bytes,4,opt,name=start,proto3,oneof"` } +type NexusWorkflowAction_Signal struct { + // Signal the target workflow. Honors DoSignal.with_start, in which case + // start_options supplies the workflow input and an existing workflow is reused. + // run_id selects the run for a signal without start. An unset DoSignal variant + // sends an empty do_actions_signal. + Signal *DoSignal `protobuf:"bytes,5,opt,name=signal,proto3,oneof"` +} + +type NexusWorkflowAction_Update struct { + // Update the target workflow selected by workflow_id and run_id. + // DoUpdate.with_start is not supported. + Update *DoUpdate `protobuf:"bytes,6,opt,name=update,proto3,oneof"` +} + func (*NexusWorkflowAction_Start) isNexusWorkflowAction_Action() {} +func (*NexusWorkflowAction_Signal) isNexusWorkflowAction_Action() {} + +func (*NexusWorkflowAction_Update) isNexusWorkflowAction_Action() {} + // Configuration for starting a kitchenSink workflow through a Nexus operation. type NexusWorkflowStartOptions struct { state protoimpl.MessageState @@ -4987,7 +5021,7 @@ var file_kitchen_sink_proto_rawDesc = []byte{ 0x65, 0x6e, 0x5f, 0x73, 0x69, 0x6e, 0x6b, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x42, 0x08, - 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xe3, 0x01, 0x0a, 0x13, 0x4e, 0x65, 0x78, + 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xe3, 0x02, 0x0a, 0x13, 0x4e, 0x65, 0x78, 0x75, 0x73, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x49, @@ -5001,7 +5035,15 @@ var file_kitchen_sink_proto_rawDesc = []byte{ 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x48, 0x00, 0x52, 0x05, 0x73, - 0x74, 0x61, 0x72, 0x74, 0x42, 0x08, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xfc, + 0x74, 0x61, 0x72, 0x74, 0x12, 0x3e, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x6c, 0x2e, + 0x6f, 0x6d, 0x65, 0x73, 0x2e, 0x6b, 0x69, 0x74, 0x63, 0x68, 0x65, 0x6e, 0x5f, 0x73, 0x69, 0x6e, + 0x6b, 0x2e, 0x44, 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x48, 0x00, 0x52, 0x06, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x6c, 0x12, 0x3e, 0x0a, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x6c, 0x2e, + 0x6f, 0x6d, 0x65, 0x73, 0x2e, 0x6b, 0x69, 0x74, 0x63, 0x68, 0x65, 0x6e, 0x5f, 0x73, 0x69, 0x6e, + 0x6b, 0x2e, 0x44, 0x6f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x06, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xfc, 0x01, 0x0a, 0x19, 0x4e, 0x65, 0x78, 0x75, 0x73, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x53, 0x74, 0x61, 0x72, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x71, 0x75, 0x65, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, @@ -5256,32 +5298,34 @@ var file_kitchen_sink_proto_depIdxs = []int32{ 25, // 109: temporal.omes.kitchen_sink.NexusOperationRequest.start_activity:type_name -> temporal.omes.kitchen_sink.ExecuteActivityAction 40, // 110: temporal.omes.kitchen_sink.NexusWorkflowAction.start_options:type_name -> temporal.omes.kitchen_sink.NexusWorkflowStartOptions 62, // 111: temporal.omes.kitchen_sink.NexusWorkflowAction.start:type_name -> google.protobuf.Empty - 69, // 112: temporal.omes.kitchen_sink.NexusWorkflowStartOptions.workflow_id_conflict_policy:type_name -> temporal.api.enums.v1.WorkflowIdConflictPolicy - 20, // 113: temporal.omes.kitchen_sink.NexusWorkflowStartOptions.workflow_input:type_name -> temporal.omes.kitchen_sink.WorkflowInput - 21, // 114: temporal.omes.kitchen_sink.DoSignal.DoSignalActions.do_actions:type_name -> temporal.omes.kitchen_sink.ActionSet - 21, // 115: temporal.omes.kitchen_sink.DoSignal.DoSignalActions.do_actions_in_main:type_name -> temporal.omes.kitchen_sink.ActionSet - 63, // 116: temporal.omes.kitchen_sink.ExecuteActivityAction.GenericActivity.arguments:type_name -> temporal.api.common.v1.Payload - 60, // 117: temporal.omes.kitchen_sink.ExecuteActivityAction.ResourcesActivity.run_for:type_name -> google.protobuf.Duration - 6, // 118: temporal.omes.kitchen_sink.ExecuteActivityAction.ClientActivity.client_sequence:type_name -> temporal.omes.kitchen_sink.ClientSequence - 60, // 119: temporal.omes.kitchen_sink.ExecuteActivityAction.TimeoutActivity.success_duration:type_name -> google.protobuf.Duration - 60, // 120: temporal.omes.kitchen_sink.ExecuteActivityAction.TimeoutActivity.failure_duration:type_name -> google.protobuf.Duration - 60, // 121: temporal.omes.kitchen_sink.ExecuteActivityAction.HeartbeatTimeoutActivity.success_duration:type_name -> google.protobuf.Duration - 60, // 122: temporal.omes.kitchen_sink.ExecuteActivityAction.HeartbeatTimeoutActivity.failure_duration:type_name -> google.protobuf.Duration - 60, // 123: temporal.omes.kitchen_sink.ExecuteActivityAction.HeartbeatTimeoutActivity.heartbeat_interval:type_name -> google.protobuf.Duration - 63, // 124: temporal.omes.kitchen_sink.ExecuteActivityAction.HeadersEntry.value:type_name -> temporal.api.common.v1.Payload - 63, // 125: temporal.omes.kitchen_sink.ExecuteChildWorkflowAction.HeadersEntry.value:type_name -> temporal.api.common.v1.Payload - 63, // 126: temporal.omes.kitchen_sink.ExecuteChildWorkflowAction.MemoEntry.value:type_name -> temporal.api.common.v1.Payload - 63, // 127: temporal.omes.kitchen_sink.ExecuteChildWorkflowAction.SearchAttributesEntry.value:type_name -> temporal.api.common.v1.Payload - 63, // 128: temporal.omes.kitchen_sink.SendSignalAction.HeadersEntry.value:type_name -> temporal.api.common.v1.Payload - 63, // 129: temporal.omes.kitchen_sink.UpsertSearchAttributesAction.SearchAttributesEntry.value:type_name -> temporal.api.common.v1.Payload - 63, // 130: temporal.omes.kitchen_sink.ContinueAsNewAction.MemoEntry.value:type_name -> temporal.api.common.v1.Payload - 63, // 131: temporal.omes.kitchen_sink.ContinueAsNewAction.HeadersEntry.value:type_name -> temporal.api.common.v1.Payload - 63, // 132: temporal.omes.kitchen_sink.ContinueAsNewAction.SearchAttributesEntry.value:type_name -> temporal.api.common.v1.Payload - 133, // [133:133] is the sub-list for method output_type - 133, // [133:133] is the sub-list for method input_type - 133, // [133:133] is the sub-list for extension type_name - 133, // [133:133] is the sub-list for extension extendee - 0, // [0:133] is the sub-list for field type_name + 13, // 112: temporal.omes.kitchen_sink.NexusWorkflowAction.signal:type_name -> temporal.omes.kitchen_sink.DoSignal + 16, // 113: temporal.omes.kitchen_sink.NexusWorkflowAction.update:type_name -> temporal.omes.kitchen_sink.DoUpdate + 69, // 114: temporal.omes.kitchen_sink.NexusWorkflowStartOptions.workflow_id_conflict_policy:type_name -> temporal.api.enums.v1.WorkflowIdConflictPolicy + 20, // 115: temporal.omes.kitchen_sink.NexusWorkflowStartOptions.workflow_input:type_name -> temporal.omes.kitchen_sink.WorkflowInput + 21, // 116: temporal.omes.kitchen_sink.DoSignal.DoSignalActions.do_actions:type_name -> temporal.omes.kitchen_sink.ActionSet + 21, // 117: temporal.omes.kitchen_sink.DoSignal.DoSignalActions.do_actions_in_main:type_name -> temporal.omes.kitchen_sink.ActionSet + 63, // 118: temporal.omes.kitchen_sink.ExecuteActivityAction.GenericActivity.arguments:type_name -> temporal.api.common.v1.Payload + 60, // 119: temporal.omes.kitchen_sink.ExecuteActivityAction.ResourcesActivity.run_for:type_name -> google.protobuf.Duration + 6, // 120: temporal.omes.kitchen_sink.ExecuteActivityAction.ClientActivity.client_sequence:type_name -> temporal.omes.kitchen_sink.ClientSequence + 60, // 121: temporal.omes.kitchen_sink.ExecuteActivityAction.TimeoutActivity.success_duration:type_name -> google.protobuf.Duration + 60, // 122: temporal.omes.kitchen_sink.ExecuteActivityAction.TimeoutActivity.failure_duration:type_name -> google.protobuf.Duration + 60, // 123: temporal.omes.kitchen_sink.ExecuteActivityAction.HeartbeatTimeoutActivity.success_duration:type_name -> google.protobuf.Duration + 60, // 124: temporal.omes.kitchen_sink.ExecuteActivityAction.HeartbeatTimeoutActivity.failure_duration:type_name -> google.protobuf.Duration + 60, // 125: temporal.omes.kitchen_sink.ExecuteActivityAction.HeartbeatTimeoutActivity.heartbeat_interval:type_name -> google.protobuf.Duration + 63, // 126: temporal.omes.kitchen_sink.ExecuteActivityAction.HeadersEntry.value:type_name -> temporal.api.common.v1.Payload + 63, // 127: temporal.omes.kitchen_sink.ExecuteChildWorkflowAction.HeadersEntry.value:type_name -> temporal.api.common.v1.Payload + 63, // 128: temporal.omes.kitchen_sink.ExecuteChildWorkflowAction.MemoEntry.value:type_name -> temporal.api.common.v1.Payload + 63, // 129: temporal.omes.kitchen_sink.ExecuteChildWorkflowAction.SearchAttributesEntry.value:type_name -> temporal.api.common.v1.Payload + 63, // 130: temporal.omes.kitchen_sink.SendSignalAction.HeadersEntry.value:type_name -> temporal.api.common.v1.Payload + 63, // 131: temporal.omes.kitchen_sink.UpsertSearchAttributesAction.SearchAttributesEntry.value:type_name -> temporal.api.common.v1.Payload + 63, // 132: temporal.omes.kitchen_sink.ContinueAsNewAction.MemoEntry.value:type_name -> temporal.api.common.v1.Payload + 63, // 133: temporal.omes.kitchen_sink.ContinueAsNewAction.HeadersEntry.value:type_name -> temporal.api.common.v1.Payload + 63, // 134: temporal.omes.kitchen_sink.ContinueAsNewAction.SearchAttributesEntry.value:type_name -> temporal.api.common.v1.Payload + 135, // [135:135] is the sub-list for method output_type + 135, // [135:135] is the sub-list for method input_type + 135, // [135:135] is the sub-list for extension type_name + 135, // [135:135] is the sub-list for extension extendee + 0, // [0:135] is the sub-list for field type_name } func init() { file_kitchen_sink_proto_init() } @@ -5907,6 +5951,8 @@ func file_kitchen_sink_proto_init() { } file_kitchen_sink_proto_msgTypes[34].OneofWrappers = []interface{}{ (*NexusWorkflowAction_Start)(nil), + (*NexusWorkflowAction_Signal)(nil), + (*NexusWorkflowAction_Update)(nil), } file_kitchen_sink_proto_msgTypes[37].OneofWrappers = []interface{}{ (*DoSignal_DoSignalActions_DoActions)(nil), diff --git a/workers/dotnet/Temporalio.Omes/protos/KitchenSink.cs b/workers/dotnet/Temporalio.Omes/protos/KitchenSink.cs index b69df2ad..72d17144 100644 --- a/workers/dotnet/Temporalio.Omes/protos/KitchenSink.cs +++ b/workers/dotnet/Temporalio.Omes/protos/KitchenSink.cs @@ -275,29 +275,32 @@ static KitchenSinkReflection() { "IAEoCUgAEkoKD3dvcmtmbG93X2FjdGlvbhgCIAEoCzIvLnRlbXBvcmFsLm9t", "ZXMua2l0Y2hlbl9zaW5rLk5leHVzV29ya2Zsb3dBY3Rpb25IABJLCg5zdGFy", "dF9hY3Rpdml0eRgDIAEoCzIxLnRlbXBvcmFsLm9tZXMua2l0Y2hlbl9zaW5r", - "LkV4ZWN1dGVBY3Rpdml0eUFjdGlvbkgAQggKBmFjdGlvbiK7AQoTTmV4dXNX", + "LkV4ZWN1dGVBY3Rpdml0eUFjdGlvbkgAQggKBmFjdGlvbiKrAgoTTmV4dXNX", "b3JrZmxvd0FjdGlvbhITCgt3b3JrZmxvd19pZBgBIAEoCRIOCgZydW5faWQY", "AiABKAkSTAoNc3RhcnRfb3B0aW9ucxgDIAEoCzI1LnRlbXBvcmFsLm9tZXMu", "a2l0Y2hlbl9zaW5rLk5leHVzV29ya2Zsb3dTdGFydE9wdGlvbnMSJwoFc3Rh", - "cnQYBCABKAsyFi5nb29nbGUucHJvdG9idWYuRW1wdHlIAEIICgZhY3Rpb24i", - "yAEKGU5leHVzV29ya2Zsb3dTdGFydE9wdGlvbnMSEgoKdGFza19xdWV1ZRgB", - "IAEoCRJUCht3b3JrZmxvd19pZF9jb25mbGljdF9wb2xpY3kYAiABKA4yLy50", - "ZW1wb3JhbC5hcGkuZW51bXMudjEuV29ya2Zsb3dJZENvbmZsaWN0UG9saWN5", - "EkEKDndvcmtmbG93X2lucHV0GAMgASgLMikudGVtcG9yYWwub21lcy5raXRj", - "aGVuX3NpbmsuV29ya2Zsb3dJbnB1dCIVChNBd2FpdFBlbmRpbmdBY3Rpb25z", - "KqQBChFQYXJlbnRDbG9zZVBvbGljeRIjCh9QQVJFTlRfQ0xPU0VfUE9MSUNZ", - "X1VOU1BFQ0lGSUVEEAASIQodUEFSRU5UX0NMT1NFX1BPTElDWV9URVJNSU5B", - "VEUQARIfChtQQVJFTlRfQ0xPU0VfUE9MSUNZX0FCQU5ET04QAhImCiJQQVJF", - "TlRfQ0xPU0VfUE9MSUNZX1JFUVVFU1RfQ0FOQ0VMEAMqQAoQVmVyc2lvbmlu", - "Z0ludGVudBIPCgtVTlNQRUNJRklFRBAAEg4KCkNPTVBBVElCTEUQARILCgdE", - "RUZBVUxUEAIqogEKHUNoaWxkV29ya2Zsb3dDYW5jZWxsYXRpb25UeXBlEhQK", - "EENISUxEX1dGX0FCQU5ET04QABIXChNDSElMRF9XRl9UUllfQ0FOQ0VMEAES", - "KAokQ0hJTERfV0ZfV0FJVF9DQU5DRUxMQVRJT05fQ09NUExFVEVEEAISKAok", - "Q0hJTERfV0ZfV0FJVF9DQU5DRUxMQVRJT05fUkVRVUVTVEVEEAMqWAoYQWN0", - "aXZpdHlDYW5jZWxsYXRpb25UeXBlEg4KClRSWV9DQU5DRUwQABIfChtXQUlU", - "X0NBTkNFTExBVElPTl9DT01QTEVURUQQARILCgdBQkFORE9OEAJCQgoQaW8u", - "dGVtcG9yYWwub21lc1ouZ2l0aHViLmNvbS90ZW1wb3JhbGlvL29tZXMvbG9h", - "ZGdlbi9raXRjaGVuc2lua2IGcHJvdG8z")); + "cnQYBCABKAsyFi5nb29nbGUucHJvdG9idWYuRW1wdHlIABI2CgZzaWduYWwY", + "BSABKAsyJC50ZW1wb3JhbC5vbWVzLmtpdGNoZW5fc2luay5Eb1NpZ25hbEgA", + "EjYKBnVwZGF0ZRgGIAEoCzIkLnRlbXBvcmFsLm9tZXMua2l0Y2hlbl9zaW5r", + "LkRvVXBkYXRlSABCCAoGYWN0aW9uIsgBChlOZXh1c1dvcmtmbG93U3RhcnRP", + "cHRpb25zEhIKCnRhc2tfcXVldWUYASABKAkSVAobd29ya2Zsb3dfaWRfY29u", + "ZmxpY3RfcG9saWN5GAIgASgOMi8udGVtcG9yYWwuYXBpLmVudW1zLnYxLldv", + "cmtmbG93SWRDb25mbGljdFBvbGljeRJBCg53b3JrZmxvd19pbnB1dBgDIAEo", + "CzIpLnRlbXBvcmFsLm9tZXMua2l0Y2hlbl9zaW5rLldvcmtmbG93SW5wdXQi", + "FQoTQXdhaXRQZW5kaW5nQWN0aW9ucyqkAQoRUGFyZW50Q2xvc2VQb2xpY3kS", + "IwofUEFSRU5UX0NMT1NFX1BPTElDWV9VTlNQRUNJRklFRBAAEiEKHVBBUkVO", + "VF9DTE9TRV9QT0xJQ1lfVEVSTUlOQVRFEAESHwobUEFSRU5UX0NMT1NFX1BP", + "TElDWV9BQkFORE9OEAISJgoiUEFSRU5UX0NMT1NFX1BPTElDWV9SRVFVRVNU", + "X0NBTkNFTBADKkAKEFZlcnNpb25pbmdJbnRlbnQSDwoLVU5TUEVDSUZJRUQQ", + "ABIOCgpDT01QQVRJQkxFEAESCwoHREVGQVVMVBACKqIBCh1DaGlsZFdvcmtm", + "bG93Q2FuY2VsbGF0aW9uVHlwZRIUChBDSElMRF9XRl9BQkFORE9OEAASFwoT", + "Q0hJTERfV0ZfVFJZX0NBTkNFTBABEigKJENISUxEX1dGX1dBSVRfQ0FOQ0VM", + "TEFUSU9OX0NPTVBMRVRFRBACEigKJENISUxEX1dGX1dBSVRfQ0FOQ0VMTEFU", + "SU9OX1JFUVVFU1RFRBADKlgKGEFjdGl2aXR5Q2FuY2VsbGF0aW9uVHlwZRIO", + "CgpUUllfQ0FOQ0VMEAASHwobV0FJVF9DQU5DRUxMQVRJT05fQ09NUExFVEVE", + "EAESCwoHQUJBTkRPThACQkIKEGlvLnRlbXBvcmFsLm9tZXNaLmdpdGh1Yi5j", + "b20vdGVtcG9yYWxpby9vbWVzL2xvYWRnZW4va2l0Y2hlbnNpbmtiBnByb3Rv", + "Mw==")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Google.Protobuf.WellKnownTypes.DurationReflection.Descriptor, global::Google.Protobuf.WellKnownTypes.EmptyReflection.Descriptor, global::Temporalio.Api.Common.V1.MessageReflection.Descriptor, global::Temporalio.Api.Failure.V1.MessageReflection.Descriptor, global::Temporalio.Api.Enums.V1.WorkflowReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Temporal.Omes.KitchenSink.ParentClosePolicy), typeof(global::Temporal.Omes.KitchenSink.VersioningIntent), typeof(global::Temporal.Omes.KitchenSink.ChildWorkflowCancellationType), typeof(global::Temporal.Omes.KitchenSink.ActivityCancellationType), }, null, new pbr::GeneratedClrTypeInfo[] { @@ -342,7 +345,7 @@ static KitchenSinkReflection() { new pbr::GeneratedClrTypeInfo(typeof(global::Temporal.Omes.KitchenSink.RemoteActivityOptions), global::Temporal.Omes.KitchenSink.RemoteActivityOptions.Parser, new[]{ "CancellationType", "DoNotEagerlyExecute", "VersioningIntent" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Temporal.Omes.KitchenSink.ExecuteNexusOperation), global::Temporal.Omes.KitchenSink.ExecuteNexusOperation.Parser, new[]{ "Endpoint", "Operation", "Input", "AwaitableChoice", "ExpectedOutput" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Temporal.Omes.KitchenSink.NexusOperationRequest), global::Temporal.Omes.KitchenSink.NexusOperationRequest.Parser, new[]{ "Echo", "WorkflowAction", "StartActivity" }, new[]{ "Action" }, null, null, null), - new pbr::GeneratedClrTypeInfo(typeof(global::Temporal.Omes.KitchenSink.NexusWorkflowAction), global::Temporal.Omes.KitchenSink.NexusWorkflowAction.Parser, new[]{ "WorkflowId", "RunId", "StartOptions", "Start" }, new[]{ "Action" }, null, null, null), + new pbr::GeneratedClrTypeInfo(typeof(global::Temporal.Omes.KitchenSink.NexusWorkflowAction), global::Temporal.Omes.KitchenSink.NexusWorkflowAction.Parser, new[]{ "WorkflowId", "RunId", "StartOptions", "Start", "Signal", "Update" }, new[]{ "Action" }, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Temporal.Omes.KitchenSink.NexusWorkflowStartOptions), global::Temporal.Omes.KitchenSink.NexusWorkflowStartOptions.Parser, new[]{ "TaskQueue", "WorkflowIdConflictPolicy", "WorkflowInput" }, null, null, null, null), new pbr::GeneratedClrTypeInfo(typeof(global::Temporal.Omes.KitchenSink.AwaitPendingActions), global::Temporal.Omes.KitchenSink.AwaitPendingActions.Parser, null, null, null, null, null) })); @@ -14749,6 +14752,12 @@ public NexusWorkflowAction(NexusWorkflowAction other) : this() { case ActionOneofCase.Start: Start = other.Start.Clone(); break; + case ActionOneofCase.Signal: + Signal = other.Signal.Clone(); + break; + case ActionOneofCase.Update: + Update = other.Update.Clone(); + break; } _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); @@ -14811,11 +14820,47 @@ public string RunId { } } + /// Field number for the "signal" field. + public const int SignalFieldNumber = 5; + /// + /// Signal the target workflow. Honors DoSignal.with_start, in which case + /// start_options supplies the workflow input and an existing workflow is reused. + /// run_id selects the run for a signal without start. An unset DoSignal variant + /// sends an empty do_actions_signal. + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Temporal.Omes.KitchenSink.DoSignal Signal { + get { return actionCase_ == ActionOneofCase.Signal ? (global::Temporal.Omes.KitchenSink.DoSignal) action_ : null; } + set { + action_ = value; + actionCase_ = value == null ? ActionOneofCase.None : ActionOneofCase.Signal; + } + } + + /// Field number for the "update" field. + public const int UpdateFieldNumber = 6; + /// + /// Update the target workflow selected by workflow_id and run_id. + /// DoUpdate.with_start is not supported. + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::Temporal.Omes.KitchenSink.DoUpdate Update { + get { return actionCase_ == ActionOneofCase.Update ? (global::Temporal.Omes.KitchenSink.DoUpdate) action_ : null; } + set { + action_ = value; + actionCase_ = value == null ? ActionOneofCase.None : ActionOneofCase.Update; + } + } + private object action_; /// Enum of possible cases for the "action" oneof. public enum ActionOneofCase { None = 0, Start = 4, + Signal = 5, + Update = 6, } private ActionOneofCase actionCase_ = ActionOneofCase.None; [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -14850,6 +14895,8 @@ public bool Equals(NexusWorkflowAction other) { if (RunId != other.RunId) return false; if (!object.Equals(StartOptions, other.StartOptions)) return false; if (!object.Equals(Start, other.Start)) return false; + if (!object.Equals(Signal, other.Signal)) return false; + if (!object.Equals(Update, other.Update)) return false; if (ActionCase != other.ActionCase) return false; return Equals(_unknownFields, other._unknownFields); } @@ -14862,6 +14909,8 @@ public override int GetHashCode() { if (RunId.Length != 0) hash ^= RunId.GetHashCode(); if (startOptions_ != null) hash ^= StartOptions.GetHashCode(); if (actionCase_ == ActionOneofCase.Start) hash ^= Start.GetHashCode(); + if (actionCase_ == ActionOneofCase.Signal) hash ^= Signal.GetHashCode(); + if (actionCase_ == ActionOneofCase.Update) hash ^= Update.GetHashCode(); hash ^= (int) actionCase_; if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); @@ -14897,6 +14946,14 @@ public void WriteTo(pb::CodedOutputStream output) { output.WriteRawTag(34); output.WriteMessage(Start); } + if (actionCase_ == ActionOneofCase.Signal) { + output.WriteRawTag(42); + output.WriteMessage(Signal); + } + if (actionCase_ == ActionOneofCase.Update) { + output.WriteRawTag(50); + output.WriteMessage(Update); + } if (_unknownFields != null) { _unknownFields.WriteTo(output); } @@ -14923,6 +14980,14 @@ public void WriteTo(pb::CodedOutputStream output) { output.WriteRawTag(34); output.WriteMessage(Start); } + if (actionCase_ == ActionOneofCase.Signal) { + output.WriteRawTag(42); + output.WriteMessage(Signal); + } + if (actionCase_ == ActionOneofCase.Update) { + output.WriteRawTag(50); + output.WriteMessage(Update); + } if (_unknownFields != null) { _unknownFields.WriteTo(ref output); } @@ -14945,6 +15010,12 @@ public int CalculateSize() { if (actionCase_ == ActionOneofCase.Start) { size += 1 + pb::CodedOutputStream.ComputeMessageSize(Start); } + if (actionCase_ == ActionOneofCase.Signal) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(Signal); + } + if (actionCase_ == ActionOneofCase.Update) { + size += 1 + pb::CodedOutputStream.ComputeMessageSize(Update); + } if (_unknownFields != null) { size += _unknownFields.CalculateSize(); } @@ -14976,6 +15047,18 @@ public void MergeFrom(NexusWorkflowAction other) { } Start.MergeFrom(other.Start); break; + case ActionOneofCase.Signal: + if (Signal == null) { + Signal = new global::Temporal.Omes.KitchenSink.DoSignal(); + } + Signal.MergeFrom(other.Signal); + break; + case ActionOneofCase.Update: + if (Update == null) { + Update = new global::Temporal.Omes.KitchenSink.DoUpdate(); + } + Update.MergeFrom(other.Update); + break; } _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); @@ -15017,6 +15100,24 @@ public void MergeFrom(pb::CodedInputStream input) { Start = subBuilder; break; } + case 42: { + global::Temporal.Omes.KitchenSink.DoSignal subBuilder = new global::Temporal.Omes.KitchenSink.DoSignal(); + if (actionCase_ == ActionOneofCase.Signal) { + subBuilder.MergeFrom(Signal); + } + input.ReadMessage(subBuilder); + Signal = subBuilder; + break; + } + case 50: { + global::Temporal.Omes.KitchenSink.DoUpdate subBuilder = new global::Temporal.Omes.KitchenSink.DoUpdate(); + if (actionCase_ == ActionOneofCase.Update) { + subBuilder.MergeFrom(Update); + } + input.ReadMessage(subBuilder); + Update = subBuilder; + break; + } } } #endif @@ -15056,6 +15157,24 @@ public void MergeFrom(pb::CodedInputStream input) { Start = subBuilder; break; } + case 42: { + global::Temporal.Omes.KitchenSink.DoSignal subBuilder = new global::Temporal.Omes.KitchenSink.DoSignal(); + if (actionCase_ == ActionOneofCase.Signal) { + subBuilder.MergeFrom(Signal); + } + input.ReadMessage(subBuilder); + Signal = subBuilder; + break; + } + case 50: { + global::Temporal.Omes.KitchenSink.DoUpdate subBuilder = new global::Temporal.Omes.KitchenSink.DoUpdate(); + if (actionCase_ == ActionOneofCase.Update) { + subBuilder.MergeFrom(Update); + } + input.ReadMessage(subBuilder); + Update = subBuilder; + break; + } } } } diff --git a/workers/go/workerlib/kitchensink/kitchen_sink.go b/workers/go/workerlib/kitchensink/kitchen_sink.go index f0889ae0..2acf941d 100644 --- a/workers/go/workerlib/kitchensink/kitchen_sink.go +++ b/workers/go/workerlib/kitchensink/kitchen_sink.go @@ -627,22 +627,26 @@ func startNexusOperation( return temporalnexus.NewSyncResult(kitchensink.ConvertToPayload(action.Echo)), nil case *kitchensink.NexusOperationRequest_WorkflowAction: workflowAction := cmp.Or(action.WorkflowAction, &kitchensink.NexusWorkflowAction{}) - if workflowAction.GetStart() == nil { - break + switch workflowAction.GetAction().(type) { + case *kitchensink.NexusWorkflowAction_Start: + startOptions := cmp.Or(workflowAction.GetStartOptions(), &kitchensink.NexusWorkflowStartOptions{}) + return temporalnexus.StartUntypedWorkflow[*common.Payload]( + ctx, + nc, + client.StartWorkflowOptions{ + ID: cmp.Or(workflowAction.GetWorkflowId(), opts.RequestID), + TaskQueue: startOptions.GetTaskQueue(), + WorkflowExecutionTimeout: 60 * time.Minute, + WorkflowIDConflictPolicy: startOptions.GetWorkflowIdConflictPolicy(), + }, + KitchenSinkWorkflow, + cmp.Or(startOptions.GetWorkflowInput(), &kitchensink.WorkflowInput{}), + ) + case *kitchensink.NexusWorkflowAction_Signal: + return signalWorkflowNexusOperation(ctx, workflowAction) + case *kitchensink.NexusWorkflowAction_Update: + return updateWorkflowNexusOperation(ctx, nc, workflowAction) } - startOptions := cmp.Or(workflowAction.GetStartOptions(), &kitchensink.NexusWorkflowStartOptions{}) - return temporalnexus.StartUntypedWorkflow[*common.Payload]( - ctx, - nc, - client.StartWorkflowOptions{ - ID: cmp.Or(workflowAction.GetWorkflowId(), opts.RequestID), - TaskQueue: startOptions.GetTaskQueue(), - WorkflowExecutionTimeout: 60 * time.Minute, - WorkflowIDConflictPolicy: startOptions.GetWorkflowIdConflictPolicy(), - }, - KitchenSinkWorkflow, - cmp.Or(startOptions.GetWorkflowInput(), &kitchensink.WorkflowInput{}), - ) case *kitchensink.NexusOperationRequest_StartActivity: return startStandaloneActivityNexusOperation(ctx, nc, action.StartActivity, opts) } @@ -650,6 +654,127 @@ func startNexusOperation( nexus.HandlerErrorTypeBadRequest, "Nexus operation request has no supported action set") } +func signalWorkflowNexusOperation( + ctx context.Context, + input *kitchensink.NexusWorkflowAction, +) (temporalnexus.TemporalOperationResult[*common.Payload], error) { + var result temporalnexus.TemporalOperationResult[*common.Payload] + if input.GetWorkflowId() == "" { + return result, nexus.HandlerErrorf( + nexus.HandlerErrorTypeBadRequest, "signal target must include a workflow ID") + } + + signal := input.GetSignal() + signalName := "do_actions_signal" + // Default to an empty action set so an operation can exercise signal + // delivery without requiring the target workflow to run another action. + var signalArg any = &kitchensink.DoSignal_DoSignalActions{ + Variant: &kitchensink.DoSignal_DoSignalActions_DoActions{ + DoActions: kitchensink.SingleActionSet(), + }, + } + if custom := signal.GetCustom(); custom != nil { + signalName = custom.GetName() + signalArg = custom.GetArgs() + } else if doActions := signal.GetDoSignalActions(); doActions != nil { + signalArg = doActions + } + + if signal.GetWithStart() { + startOptions := client.StartWorkflowOptions{ + ID: input.GetWorkflowId(), + TaskQueue: input.GetStartOptions().GetTaskQueue(), + WorkflowExecutionTimeout: 60 * time.Minute, + WorkflowIDConflictPolicy: enumspb.WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING, + } + if startOptions.TaskQueue == "" { + // Default to the task queue handling this Nexus request. + startOptions.TaskQueue = temporalnexus.GetOperationInfo(ctx).TaskQueue + } + workflowInput := cmp.Or(input.GetStartOptions().GetWorkflowInput(), &kitchensink.WorkflowInput{}) + run, err := temporalnexus.GetClient(ctx).SignalWithStartWorkflow( + ctx, input.GetWorkflowId(), signalName, signalArg, startOptions, + KitchenSinkWorkflow, workflowInput) + if err != nil { + return result, nexusOutboundError("SignalWithStartWorkflow", err) + } + return temporalnexus.NewSyncResult(kitchensink.ConvertToPayload(run.GetID())), nil + } + + err := temporalnexus.GetClient(ctx).SignalWorkflow( + ctx, input.GetWorkflowId(), input.GetRunId(), signalName, signalArg) + if err != nil { + return result, nexusOutboundError("SignalWorkflow", err) + } + return temporalnexus.NewSyncResult(kitchensink.ConvertToPayload(input.GetWorkflowId())), nil +} +func updateWorkflowNexusOperation( + ctx context.Context, + nc temporalnexus.NexusClient, + input *kitchensink.NexusWorkflowAction, +) (temporalnexus.TemporalOperationResult[*common.Payload], error) { + var result temporalnexus.TemporalOperationResult[*common.Payload] + if input.GetWorkflowId() == "" { + return result, nexus.HandlerErrorf( + nexus.HandlerErrorTypeBadRequest, "update target must include a workflow ID") + } + if input.GetUpdate().GetWithStart() { + return result, nexus.HandlerErrorf( + nexus.HandlerErrorTypeBadRequest, "update-with-start is not supported by this Nexus operation") + } + + updateName := "do_actions_update" + var args []any + if custom := input.GetUpdate().GetCustom(); custom != nil { + updateName = custom.GetName() + args = []any{custom.GetArgs()} + } else { + update := cmp.Or(input.GetUpdate().GetDoActions(), &kitchensink.DoActionsUpdate{ + Variant: &kitchensink.DoActionsUpdate_DoActions{ + DoActions: kitchensink.SingleActionSet( + kitchensink.NewNexusUpdateResultAction(input.GetWorkflowId()), + ), + }, + }) + args = []any{update} + } + + // UpdateID is deliberately left unset: StartUpdateWorkflow derives it from the + // Nexus request ID, so a retried Nexus task attaches to the original update + // rather than starting a second one. + result, err := temporalnexus.StartUpdateWorkflow[*common.Payload](ctx, nc, client.UpdateWorkflowOptions{ + WorkflowID: input.GetWorkflowId(), + RunID: input.GetRunId(), + UpdateName: updateName, + Args: args, + // Accepted is the only stage a Nexus-backed update supports: the operation + // goes async once the update is accepted, and the update's result reaches + // the caller later through the operation's completion callback. + WaitForStage: client.WorkflowUpdateStageAccepted, + }) + if err != nil { + return result, nexusOutboundError("UpdateWorkflow", err) + } + return result, nil +} + +// nexusOutboundError maps a failure from an RPC the handler issued to the right +// Nexus handler error. Namespace handover is worth retrying; a disabled server +// feature or a bad target is not, because no number of retries fixes either. +func nexusOutboundError(rpc string, err error) error { + var notActive *serviceerror.NamespaceNotActive + if errors.As(err, ¬Active) { + return nexus.HandlerErrorf(nexus.HandlerErrorTypeUnavailable, "%s", err.Error()) + } + var unimplemented *serviceerror.Unimplemented + var invalidArg *serviceerror.InvalidArgument + var notFound *serviceerror.NotFound + if errors.As(err, &unimplemented) || errors.As(err, &invalidArg) || errors.As(err, ¬Found) { + return nexus.HandlerErrorf(nexus.HandlerErrorTypeBadRequest, "%s failed: %s", rpc, err.Error()) + } + return fmt.Errorf("%s failed: %w", rpc, err) +} + // startStandaloneActivityNexusOperation starts the registered "noop" activity. func startStandaloneActivityNexusOperation( ctx context.Context, diff --git a/workers/java/io/temporal/omes/KitchenSink.java b/workers/java/io/temporal/omes/KitchenSink.java index f1b98888..44563e37 100644 --- a/workers/java/io/temporal/omes/KitchenSink.java +++ b/workers/java/io/temporal/omes/KitchenSink.java @@ -56651,6 +56651,72 @@ public interface NexusWorkflowActionOrBuilder extends */ com.google.protobuf.EmptyOrBuilder getStartOrBuilder(); + /** + *
+     * Signal the target workflow. Honors DoSignal.with_start, in which case
+     * start_options supplies the workflow input and an existing workflow is reused.
+     * run_id selects the run for a signal without start. An unset DoSignal variant
+     * sends an empty do_actions_signal.
+     * 
+ * + * .temporal.omes.kitchen_sink.DoSignal signal = 5; + * @return Whether the signal field is set. + */ + boolean hasSignal(); + /** + *
+     * Signal the target workflow. Honors DoSignal.with_start, in which case
+     * start_options supplies the workflow input and an existing workflow is reused.
+     * run_id selects the run for a signal without start. An unset DoSignal variant
+     * sends an empty do_actions_signal.
+     * 
+ * + * .temporal.omes.kitchen_sink.DoSignal signal = 5; + * @return The signal. + */ + io.temporal.omes.KitchenSink.DoSignal getSignal(); + /** + *
+     * Signal the target workflow. Honors DoSignal.with_start, in which case
+     * start_options supplies the workflow input and an existing workflow is reused.
+     * run_id selects the run for a signal without start. An unset DoSignal variant
+     * sends an empty do_actions_signal.
+     * 
+ * + * .temporal.omes.kitchen_sink.DoSignal signal = 5; + */ + io.temporal.omes.KitchenSink.DoSignalOrBuilder getSignalOrBuilder(); + + /** + *
+     * Update the target workflow selected by workflow_id and run_id.
+     * DoUpdate.with_start is not supported.
+     * 
+ * + * .temporal.omes.kitchen_sink.DoUpdate update = 6; + * @return Whether the update field is set. + */ + boolean hasUpdate(); + /** + *
+     * Update the target workflow selected by workflow_id and run_id.
+     * DoUpdate.with_start is not supported.
+     * 
+ * + * .temporal.omes.kitchen_sink.DoUpdate update = 6; + * @return The update. + */ + io.temporal.omes.KitchenSink.DoUpdate getUpdate(); + /** + *
+     * Update the target workflow selected by workflow_id and run_id.
+     * DoUpdate.with_start is not supported.
+     * 
+ * + * .temporal.omes.kitchen_sink.DoUpdate update = 6; + */ + io.temporal.omes.KitchenSink.DoUpdateOrBuilder getUpdateOrBuilder(); + io.temporal.omes.KitchenSink.NexusWorkflowAction.ActionCase getActionCase(); } /** @@ -56698,6 +56764,8 @@ public enum ActionCase implements com.google.protobuf.Internal.EnumLite, com.google.protobuf.AbstractMessage.InternalOneOfEnum { START(4), + SIGNAL(5), + UPDATE(6), ACTION_NOT_SET(0); private final int value; private ActionCase(int value) { @@ -56716,6 +56784,8 @@ public static ActionCase valueOf(int value) { public static ActionCase forNumber(int value) { switch (value) { case 4: return START; + case 5: return SIGNAL; + case 6: return UPDATE; case 0: return ACTION_NOT_SET; default: return null; } @@ -56878,6 +56948,104 @@ public com.google.protobuf.EmptyOrBuilder getStartOrBuilder() { return com.google.protobuf.Empty.getDefaultInstance(); } + public static final int SIGNAL_FIELD_NUMBER = 5; + /** + *
+     * Signal the target workflow. Honors DoSignal.with_start, in which case
+     * start_options supplies the workflow input and an existing workflow is reused.
+     * run_id selects the run for a signal without start. An unset DoSignal variant
+     * sends an empty do_actions_signal.
+     * 
+ * + * .temporal.omes.kitchen_sink.DoSignal signal = 5; + * @return Whether the signal field is set. + */ + @java.lang.Override + public boolean hasSignal() { + return actionCase_ == 5; + } + /** + *
+     * Signal the target workflow. Honors DoSignal.with_start, in which case
+     * start_options supplies the workflow input and an existing workflow is reused.
+     * run_id selects the run for a signal without start. An unset DoSignal variant
+     * sends an empty do_actions_signal.
+     * 
+ * + * .temporal.omes.kitchen_sink.DoSignal signal = 5; + * @return The signal. + */ + @java.lang.Override + public io.temporal.omes.KitchenSink.DoSignal getSignal() { + if (actionCase_ == 5) { + return (io.temporal.omes.KitchenSink.DoSignal) action_; + } + return io.temporal.omes.KitchenSink.DoSignal.getDefaultInstance(); + } + /** + *
+     * Signal the target workflow. Honors DoSignal.with_start, in which case
+     * start_options supplies the workflow input and an existing workflow is reused.
+     * run_id selects the run for a signal without start. An unset DoSignal variant
+     * sends an empty do_actions_signal.
+     * 
+ * + * .temporal.omes.kitchen_sink.DoSignal signal = 5; + */ + @java.lang.Override + public io.temporal.omes.KitchenSink.DoSignalOrBuilder getSignalOrBuilder() { + if (actionCase_ == 5) { + return (io.temporal.omes.KitchenSink.DoSignal) action_; + } + return io.temporal.omes.KitchenSink.DoSignal.getDefaultInstance(); + } + + public static final int UPDATE_FIELD_NUMBER = 6; + /** + *
+     * Update the target workflow selected by workflow_id and run_id.
+     * DoUpdate.with_start is not supported.
+     * 
+ * + * .temporal.omes.kitchen_sink.DoUpdate update = 6; + * @return Whether the update field is set. + */ + @java.lang.Override + public boolean hasUpdate() { + return actionCase_ == 6; + } + /** + *
+     * Update the target workflow selected by workflow_id and run_id.
+     * DoUpdate.with_start is not supported.
+     * 
+ * + * .temporal.omes.kitchen_sink.DoUpdate update = 6; + * @return The update. + */ + @java.lang.Override + public io.temporal.omes.KitchenSink.DoUpdate getUpdate() { + if (actionCase_ == 6) { + return (io.temporal.omes.KitchenSink.DoUpdate) action_; + } + return io.temporal.omes.KitchenSink.DoUpdate.getDefaultInstance(); + } + /** + *
+     * Update the target workflow selected by workflow_id and run_id.
+     * DoUpdate.with_start is not supported.
+     * 
+ * + * .temporal.omes.kitchen_sink.DoUpdate update = 6; + */ + @java.lang.Override + public io.temporal.omes.KitchenSink.DoUpdateOrBuilder getUpdateOrBuilder() { + if (actionCase_ == 6) { + return (io.temporal.omes.KitchenSink.DoUpdate) action_; + } + return io.temporal.omes.KitchenSink.DoUpdate.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; @java.lang.Override public final boolean isInitialized() { @@ -56904,6 +57072,12 @@ public void writeTo(com.google.protobuf.CodedOutputStream output) if (actionCase_ == 4) { output.writeMessage(4, (com.google.protobuf.Empty) action_); } + if (actionCase_ == 5) { + output.writeMessage(5, (io.temporal.omes.KitchenSink.DoSignal) action_); + } + if (actionCase_ == 6) { + output.writeMessage(6, (io.temporal.omes.KitchenSink.DoUpdate) action_); + } getUnknownFields().writeTo(output); } @@ -56927,6 +57101,14 @@ public int getSerializedSize() { size += com.google.protobuf.CodedOutputStream .computeMessageSize(4, (com.google.protobuf.Empty) action_); } + if (actionCase_ == 5) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(5, (io.temporal.omes.KitchenSink.DoSignal) action_); + } + if (actionCase_ == 6) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(6, (io.temporal.omes.KitchenSink.DoUpdate) action_); + } size += getUnknownFields().getSerializedSize(); memoizedSize = size; return size; @@ -56957,6 +57139,14 @@ public boolean equals(final java.lang.Object obj) { if (!getStart() .equals(other.getStart())) return false; break; + case 5: + if (!getSignal() + .equals(other.getSignal())) return false; + break; + case 6: + if (!getUpdate() + .equals(other.getUpdate())) return false; + break; case 0: default: } @@ -56984,6 +57174,14 @@ public int hashCode() { hash = (37 * hash) + START_FIELD_NUMBER; hash = (53 * hash) + getStart().hashCode(); break; + case 5: + hash = (37 * hash) + SIGNAL_FIELD_NUMBER; + hash = (53 * hash) + getSignal().hashCode(); + break; + case 6: + hash = (37 * hash) + UPDATE_FIELD_NUMBER; + hash = (53 * hash) + getUpdate().hashCode(); + break; case 0: default: } @@ -57134,6 +57332,12 @@ public Builder clear() { if (startBuilder_ != null) { startBuilder_.clear(); } + if (signalBuilder_ != null) { + signalBuilder_.clear(); + } + if (updateBuilder_ != null) { + updateBuilder_.clear(); + } actionCase_ = 0; action_ = null; return this; @@ -57193,6 +57397,14 @@ private void buildPartialOneofs(io.temporal.omes.KitchenSink.NexusWorkflowAction startBuilder_ != null) { result.action_ = startBuilder_.build(); } + if (actionCase_ == 5 && + signalBuilder_ != null) { + result.action_ = signalBuilder_.build(); + } + if (actionCase_ == 6 && + updateBuilder_ != null) { + result.action_ = updateBuilder_.build(); + } } @java.lang.Override @@ -57257,6 +57469,14 @@ public Builder mergeFrom(io.temporal.omes.KitchenSink.NexusWorkflowAction other) mergeStart(other.getStart()); break; } + case SIGNAL: { + mergeSignal(other.getSignal()); + break; + } + case UPDATE: { + mergeUpdate(other.getUpdate()); + break; + } case ACTION_NOT_SET: { break; } @@ -57311,6 +57531,20 @@ public Builder mergeFrom( actionCase_ = 4; break; } // case 34 + case 42: { + input.readMessage( + getSignalFieldBuilder().getBuilder(), + extensionRegistry); + actionCase_ = 5; + break; + } // case 42 + case 50: { + input.readMessage( + getUpdateFieldBuilder().getBuilder(), + extensionRegistry); + actionCase_ = 6; + break; + } // case 50 default: { if (!super.parseUnknownField(input, extensionRegistry, tag)) { done = true; // was an endgroup tag @@ -57785,6 +58019,398 @@ public com.google.protobuf.EmptyOrBuilder getStartOrBuilder() { onChanged(); return startBuilder_; } + + private com.google.protobuf.SingleFieldBuilderV3< + io.temporal.omes.KitchenSink.DoSignal, io.temporal.omes.KitchenSink.DoSignal.Builder, io.temporal.omes.KitchenSink.DoSignalOrBuilder> signalBuilder_; + /** + *
+       * Signal the target workflow. Honors DoSignal.with_start, in which case
+       * start_options supplies the workflow input and an existing workflow is reused.
+       * run_id selects the run for a signal without start. An unset DoSignal variant
+       * sends an empty do_actions_signal.
+       * 
+ * + * .temporal.omes.kitchen_sink.DoSignal signal = 5; + * @return Whether the signal field is set. + */ + @java.lang.Override + public boolean hasSignal() { + return actionCase_ == 5; + } + /** + *
+       * Signal the target workflow. Honors DoSignal.with_start, in which case
+       * start_options supplies the workflow input and an existing workflow is reused.
+       * run_id selects the run for a signal without start. An unset DoSignal variant
+       * sends an empty do_actions_signal.
+       * 
+ * + * .temporal.omes.kitchen_sink.DoSignal signal = 5; + * @return The signal. + */ + @java.lang.Override + public io.temporal.omes.KitchenSink.DoSignal getSignal() { + if (signalBuilder_ == null) { + if (actionCase_ == 5) { + return (io.temporal.omes.KitchenSink.DoSignal) action_; + } + return io.temporal.omes.KitchenSink.DoSignal.getDefaultInstance(); + } else { + if (actionCase_ == 5) { + return signalBuilder_.getMessage(); + } + return io.temporal.omes.KitchenSink.DoSignal.getDefaultInstance(); + } + } + /** + *
+       * Signal the target workflow. Honors DoSignal.with_start, in which case
+       * start_options supplies the workflow input and an existing workflow is reused.
+       * run_id selects the run for a signal without start. An unset DoSignal variant
+       * sends an empty do_actions_signal.
+       * 
+ * + * .temporal.omes.kitchen_sink.DoSignal signal = 5; + */ + public Builder setSignal(io.temporal.omes.KitchenSink.DoSignal value) { + if (signalBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + action_ = value; + onChanged(); + } else { + signalBuilder_.setMessage(value); + } + actionCase_ = 5; + return this; + } + /** + *
+       * Signal the target workflow. Honors DoSignal.with_start, in which case
+       * start_options supplies the workflow input and an existing workflow is reused.
+       * run_id selects the run for a signal without start. An unset DoSignal variant
+       * sends an empty do_actions_signal.
+       * 
+ * + * .temporal.omes.kitchen_sink.DoSignal signal = 5; + */ + public Builder setSignal( + io.temporal.omes.KitchenSink.DoSignal.Builder builderForValue) { + if (signalBuilder_ == null) { + action_ = builderForValue.build(); + onChanged(); + } else { + signalBuilder_.setMessage(builderForValue.build()); + } + actionCase_ = 5; + return this; + } + /** + *
+       * Signal the target workflow. Honors DoSignal.with_start, in which case
+       * start_options supplies the workflow input and an existing workflow is reused.
+       * run_id selects the run for a signal without start. An unset DoSignal variant
+       * sends an empty do_actions_signal.
+       * 
+ * + * .temporal.omes.kitchen_sink.DoSignal signal = 5; + */ + public Builder mergeSignal(io.temporal.omes.KitchenSink.DoSignal value) { + if (signalBuilder_ == null) { + if (actionCase_ == 5 && + action_ != io.temporal.omes.KitchenSink.DoSignal.getDefaultInstance()) { + action_ = io.temporal.omes.KitchenSink.DoSignal.newBuilder((io.temporal.omes.KitchenSink.DoSignal) action_) + .mergeFrom(value).buildPartial(); + } else { + action_ = value; + } + onChanged(); + } else { + if (actionCase_ == 5) { + signalBuilder_.mergeFrom(value); + } else { + signalBuilder_.setMessage(value); + } + } + actionCase_ = 5; + return this; + } + /** + *
+       * Signal the target workflow. Honors DoSignal.with_start, in which case
+       * start_options supplies the workflow input and an existing workflow is reused.
+       * run_id selects the run for a signal without start. An unset DoSignal variant
+       * sends an empty do_actions_signal.
+       * 
+ * + * .temporal.omes.kitchen_sink.DoSignal signal = 5; + */ + public Builder clearSignal() { + if (signalBuilder_ == null) { + if (actionCase_ == 5) { + actionCase_ = 0; + action_ = null; + onChanged(); + } + } else { + if (actionCase_ == 5) { + actionCase_ = 0; + action_ = null; + } + signalBuilder_.clear(); + } + return this; + } + /** + *
+       * Signal the target workflow. Honors DoSignal.with_start, in which case
+       * start_options supplies the workflow input and an existing workflow is reused.
+       * run_id selects the run for a signal without start. An unset DoSignal variant
+       * sends an empty do_actions_signal.
+       * 
+ * + * .temporal.omes.kitchen_sink.DoSignal signal = 5; + */ + public io.temporal.omes.KitchenSink.DoSignal.Builder getSignalBuilder() { + return getSignalFieldBuilder().getBuilder(); + } + /** + *
+       * Signal the target workflow. Honors DoSignal.with_start, in which case
+       * start_options supplies the workflow input and an existing workflow is reused.
+       * run_id selects the run for a signal without start. An unset DoSignal variant
+       * sends an empty do_actions_signal.
+       * 
+ * + * .temporal.omes.kitchen_sink.DoSignal signal = 5; + */ + @java.lang.Override + public io.temporal.omes.KitchenSink.DoSignalOrBuilder getSignalOrBuilder() { + if ((actionCase_ == 5) && (signalBuilder_ != null)) { + return signalBuilder_.getMessageOrBuilder(); + } else { + if (actionCase_ == 5) { + return (io.temporal.omes.KitchenSink.DoSignal) action_; + } + return io.temporal.omes.KitchenSink.DoSignal.getDefaultInstance(); + } + } + /** + *
+       * Signal the target workflow. Honors DoSignal.with_start, in which case
+       * start_options supplies the workflow input and an existing workflow is reused.
+       * run_id selects the run for a signal without start. An unset DoSignal variant
+       * sends an empty do_actions_signal.
+       * 
+ * + * .temporal.omes.kitchen_sink.DoSignal signal = 5; + */ + private com.google.protobuf.SingleFieldBuilderV3< + io.temporal.omes.KitchenSink.DoSignal, io.temporal.omes.KitchenSink.DoSignal.Builder, io.temporal.omes.KitchenSink.DoSignalOrBuilder> + getSignalFieldBuilder() { + if (signalBuilder_ == null) { + if (!(actionCase_ == 5)) { + action_ = io.temporal.omes.KitchenSink.DoSignal.getDefaultInstance(); + } + signalBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + io.temporal.omes.KitchenSink.DoSignal, io.temporal.omes.KitchenSink.DoSignal.Builder, io.temporal.omes.KitchenSink.DoSignalOrBuilder>( + (io.temporal.omes.KitchenSink.DoSignal) action_, + getParentForChildren(), + isClean()); + action_ = null; + } + actionCase_ = 5; + onChanged(); + return signalBuilder_; + } + + private com.google.protobuf.SingleFieldBuilderV3< + io.temporal.omes.KitchenSink.DoUpdate, io.temporal.omes.KitchenSink.DoUpdate.Builder, io.temporal.omes.KitchenSink.DoUpdateOrBuilder> updateBuilder_; + /** + *
+       * Update the target workflow selected by workflow_id and run_id.
+       * DoUpdate.with_start is not supported.
+       * 
+ * + * .temporal.omes.kitchen_sink.DoUpdate update = 6; + * @return Whether the update field is set. + */ + @java.lang.Override + public boolean hasUpdate() { + return actionCase_ == 6; + } + /** + *
+       * Update the target workflow selected by workflow_id and run_id.
+       * DoUpdate.with_start is not supported.
+       * 
+ * + * .temporal.omes.kitchen_sink.DoUpdate update = 6; + * @return The update. + */ + @java.lang.Override + public io.temporal.omes.KitchenSink.DoUpdate getUpdate() { + if (updateBuilder_ == null) { + if (actionCase_ == 6) { + return (io.temporal.omes.KitchenSink.DoUpdate) action_; + } + return io.temporal.omes.KitchenSink.DoUpdate.getDefaultInstance(); + } else { + if (actionCase_ == 6) { + return updateBuilder_.getMessage(); + } + return io.temporal.omes.KitchenSink.DoUpdate.getDefaultInstance(); + } + } + /** + *
+       * Update the target workflow selected by workflow_id and run_id.
+       * DoUpdate.with_start is not supported.
+       * 
+ * + * .temporal.omes.kitchen_sink.DoUpdate update = 6; + */ + public Builder setUpdate(io.temporal.omes.KitchenSink.DoUpdate value) { + if (updateBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + action_ = value; + onChanged(); + } else { + updateBuilder_.setMessage(value); + } + actionCase_ = 6; + return this; + } + /** + *
+       * Update the target workflow selected by workflow_id and run_id.
+       * DoUpdate.with_start is not supported.
+       * 
+ * + * .temporal.omes.kitchen_sink.DoUpdate update = 6; + */ + public Builder setUpdate( + io.temporal.omes.KitchenSink.DoUpdate.Builder builderForValue) { + if (updateBuilder_ == null) { + action_ = builderForValue.build(); + onChanged(); + } else { + updateBuilder_.setMessage(builderForValue.build()); + } + actionCase_ = 6; + return this; + } + /** + *
+       * Update the target workflow selected by workflow_id and run_id.
+       * DoUpdate.with_start is not supported.
+       * 
+ * + * .temporal.omes.kitchen_sink.DoUpdate update = 6; + */ + public Builder mergeUpdate(io.temporal.omes.KitchenSink.DoUpdate value) { + if (updateBuilder_ == null) { + if (actionCase_ == 6 && + action_ != io.temporal.omes.KitchenSink.DoUpdate.getDefaultInstance()) { + action_ = io.temporal.omes.KitchenSink.DoUpdate.newBuilder((io.temporal.omes.KitchenSink.DoUpdate) action_) + .mergeFrom(value).buildPartial(); + } else { + action_ = value; + } + onChanged(); + } else { + if (actionCase_ == 6) { + updateBuilder_.mergeFrom(value); + } else { + updateBuilder_.setMessage(value); + } + } + actionCase_ = 6; + return this; + } + /** + *
+       * Update the target workflow selected by workflow_id and run_id.
+       * DoUpdate.with_start is not supported.
+       * 
+ * + * .temporal.omes.kitchen_sink.DoUpdate update = 6; + */ + public Builder clearUpdate() { + if (updateBuilder_ == null) { + if (actionCase_ == 6) { + actionCase_ = 0; + action_ = null; + onChanged(); + } + } else { + if (actionCase_ == 6) { + actionCase_ = 0; + action_ = null; + } + updateBuilder_.clear(); + } + return this; + } + /** + *
+       * Update the target workflow selected by workflow_id and run_id.
+       * DoUpdate.with_start is not supported.
+       * 
+ * + * .temporal.omes.kitchen_sink.DoUpdate update = 6; + */ + public io.temporal.omes.KitchenSink.DoUpdate.Builder getUpdateBuilder() { + return getUpdateFieldBuilder().getBuilder(); + } + /** + *
+       * Update the target workflow selected by workflow_id and run_id.
+       * DoUpdate.with_start is not supported.
+       * 
+ * + * .temporal.omes.kitchen_sink.DoUpdate update = 6; + */ + @java.lang.Override + public io.temporal.omes.KitchenSink.DoUpdateOrBuilder getUpdateOrBuilder() { + if ((actionCase_ == 6) && (updateBuilder_ != null)) { + return updateBuilder_.getMessageOrBuilder(); + } else { + if (actionCase_ == 6) { + return (io.temporal.omes.KitchenSink.DoUpdate) action_; + } + return io.temporal.omes.KitchenSink.DoUpdate.getDefaultInstance(); + } + } + /** + *
+       * Update the target workflow selected by workflow_id and run_id.
+       * DoUpdate.with_start is not supported.
+       * 
+ * + * .temporal.omes.kitchen_sink.DoUpdate update = 6; + */ + private com.google.protobuf.SingleFieldBuilderV3< + io.temporal.omes.KitchenSink.DoUpdate, io.temporal.omes.KitchenSink.DoUpdate.Builder, io.temporal.omes.KitchenSink.DoUpdateOrBuilder> + getUpdateFieldBuilder() { + if (updateBuilder_ == null) { + if (!(actionCase_ == 6)) { + action_ = io.temporal.omes.KitchenSink.DoUpdate.getDefaultInstance(); + } + updateBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + io.temporal.omes.KitchenSink.DoUpdate, io.temporal.omes.KitchenSink.DoUpdate.Builder, io.temporal.omes.KitchenSink.DoUpdateOrBuilder>( + (io.temporal.omes.KitchenSink.DoUpdate) action_, + getParentForChildren(), + isClean()); + action_ = null; + } + actionCase_ = 6; + onChanged(); + return updateBuilder_; + } @java.lang.Override public final Builder setUnknownFields( final com.google.protobuf.UnknownFieldSet unknownFields) { @@ -59828,31 +60454,34 @@ public io.temporal.omes.KitchenSink.AwaitPendingActions getDefaultInstanceForTyp "al.omes.kitchen_sink.NexusWorkflowAction" + "H\000\022K\n\016start_activity\030\003 \001(\01321.temporal.om" + "es.kitchen_sink.ExecuteActivityActionH\000B" + - "\010\n\006action\"\273\001\n\023NexusWorkflowAction\022\023\n\013wor" + + "\010\n\006action\"\253\002\n\023NexusWorkflowAction\022\023\n\013wor" + "kflow_id\030\001 \001(\t\022\016\n\006run_id\030\002 \001(\t\022L\n\rstart_" + "options\030\003 \001(\01325.temporal.omes.kitchen_si" + "nk.NexusWorkflowStartOptions\022\'\n\005start\030\004 " + - "\001(\0132\026.google.protobuf.EmptyH\000B\010\n\006action\"" + - "\310\001\n\031NexusWorkflowStartOptions\022\022\n\ntask_qu" + - "eue\030\001 \001(\t\022T\n\033workflow_id_conflict_policy" + - "\030\002 \001(\0162/.temporal.api.enums.v1.WorkflowI" + - "dConflictPolicy\022A\n\016workflow_input\030\003 \001(\0132" + - ").temporal.omes.kitchen_sink.WorkflowInp" + - "ut\"\025\n\023AwaitPendingActions*\244\001\n\021ParentClos" + - "ePolicy\022#\n\037PARENT_CLOSE_POLICY_UNSPECIFI" + - "ED\020\000\022!\n\035PARENT_CLOSE_POLICY_TERMINATE\020\001\022" + - "\037\n\033PARENT_CLOSE_POLICY_ABANDON\020\002\022&\n\"PARE" + - "NT_CLOSE_POLICY_REQUEST_CANCEL\020\003*@\n\020Vers" + - "ioningIntent\022\017\n\013UNSPECIFIED\020\000\022\016\n\nCOMPATI" + - "BLE\020\001\022\013\n\007DEFAULT\020\002*\242\001\n\035ChildWorkflowCanc" + - "ellationType\022\024\n\020CHILD_WF_ABANDON\020\000\022\027\n\023CH" + - "ILD_WF_TRY_CANCEL\020\001\022(\n$CHILD_WF_WAIT_CAN" + - "CELLATION_COMPLETED\020\002\022(\n$CHILD_WF_WAIT_C" + - "ANCELLATION_REQUESTED\020\003*X\n\030ActivityCance" + - "llationType\022\016\n\nTRY_CANCEL\020\000\022\037\n\033WAIT_CANC" + - "ELLATION_COMPLETED\020\001\022\013\n\007ABANDON\020\002BB\n\020io." + - "temporal.omesZ.github.com/temporalio/ome" + - "s/loadgen/kitchensinkb\006proto3" + "\001(\0132\026.google.protobuf.EmptyH\000\0226\n\006signal\030" + + "\005 \001(\0132$.temporal.omes.kitchen_sink.DoSig" + + "nalH\000\0226\n\006update\030\006 \001(\0132$.temporal.omes.ki" + + "tchen_sink.DoUpdateH\000B\010\n\006action\"\310\001\n\031Nexu" + + "sWorkflowStartOptions\022\022\n\ntask_queue\030\001 \001(" + + "\t\022T\n\033workflow_id_conflict_policy\030\002 \001(\0162/" + + ".temporal.api.enums.v1.WorkflowIdConflic" + + "tPolicy\022A\n\016workflow_input\030\003 \001(\0132).tempor" + + "al.omes.kitchen_sink.WorkflowInput\"\025\n\023Aw" + + "aitPendingActions*\244\001\n\021ParentClosePolicy\022" + + "#\n\037PARENT_CLOSE_POLICY_UNSPECIFIED\020\000\022!\n\035" + + "PARENT_CLOSE_POLICY_TERMINATE\020\001\022\037\n\033PAREN" + + "T_CLOSE_POLICY_ABANDON\020\002\022&\n\"PARENT_CLOSE" + + "_POLICY_REQUEST_CANCEL\020\003*@\n\020VersioningIn" + + "tent\022\017\n\013UNSPECIFIED\020\000\022\016\n\nCOMPATIBLE\020\001\022\013\n" + + "\007DEFAULT\020\002*\242\001\n\035ChildWorkflowCancellation" + + "Type\022\024\n\020CHILD_WF_ABANDON\020\000\022\027\n\023CHILD_WF_T" + + "RY_CANCEL\020\001\022(\n$CHILD_WF_WAIT_CANCELLATIO" + + "N_COMPLETED\020\002\022(\n$CHILD_WF_WAIT_CANCELLAT" + + "ION_REQUESTED\020\003*X\n\030ActivityCancellationT" + + "ype\022\016\n\nTRY_CANCEL\020\000\022\037\n\033WAIT_CANCELLATION" + + "_COMPLETED\020\001\022\013\n\007ABANDON\020\002BB\n\020io.temporal" + + ".omesZ.github.com/temporalio/omes/loadge" + + "n/kitchensinkb\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor .internalBuildGeneratedFileFrom(descriptorData, @@ -60180,7 +60809,7 @@ public io.temporal.omes.KitchenSink.AwaitPendingActions getDefaultInstanceForTyp internal_static_temporal_omes_kitchen_sink_NexusWorkflowAction_fieldAccessorTable = new com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( internal_static_temporal_omes_kitchen_sink_NexusWorkflowAction_descriptor, - new java.lang.String[] { "WorkflowId", "RunId", "StartOptions", "Start", "Action", }); + new java.lang.String[] { "WorkflowId", "RunId", "StartOptions", "Start", "Signal", "Update", "Action", }); internal_static_temporal_omes_kitchen_sink_NexusWorkflowStartOptions_descriptor = getDescriptor().getMessageTypes().get(35); internal_static_temporal_omes_kitchen_sink_NexusWorkflowStartOptions_fieldAccessorTable = new diff --git a/workers/proto/kitchen_sink/kitchen_sink.proto b/workers/proto/kitchen_sink/kitchen_sink.proto index 3af436ef..b3b6aca2 100644 --- a/workers/proto/kitchen_sink/kitchen_sink.proto +++ b/workers/proto/kitchen_sink/kitchen_sink.proto @@ -558,6 +558,14 @@ message NexusWorkflowAction { NexusWorkflowStartOptions start_options = 3; oneof action { google.protobuf.Empty start = 4; + // Signal the target workflow. Honors DoSignal.with_start, in which case + // start_options supplies the workflow input and an existing workflow is reused. + // run_id selects the run for a signal without start. An unset DoSignal variant + // sends an empty do_actions_signal. + DoSignal signal = 5; + // Update the target workflow selected by workflow_id and run_id. + // DoUpdate.with_start is not supported. + DoUpdate update = 6; } } diff --git a/workers/python/protos/kitchen_sink_pb2.py b/workers/python/protos/kitchen_sink_pb2.py index 2b2ece06..dabac844 100644 --- a/workers/python/protos/kitchen_sink_pb2.py +++ b/workers/python/protos/kitchen_sink_pb2.py @@ -19,7 +19,7 @@ from temporalio.api.enums.v1 import workflow_pb2 as temporal_dot_api_dot_enums_dot_v1_dot_workflow__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x12kitchen_sink.proto\x12\x1atemporal.omes.kitchen_sink\x1a\x1egoogle/protobuf/duration.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a$temporal/api/common/v1/message.proto\x1a%temporal/api/failure/v1/message.proto\x1a$temporal/api/enums/v1/workflow.proto\"\xe1\x01\n\tTestInput\x12\x41\n\x0eworkflow_input\x18\x01 \x01(\x0b\x32).temporal.omes.kitchen_sink.WorkflowInput\x12\x43\n\x0f\x63lient_sequence\x18\x02 \x01(\x0b\x32*.temporal.omes.kitchen_sink.ClientSequence\x12L\n\x11with_start_action\x18\x03 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.WithStartClientAction\"R\n\x0e\x43lientSequence\x12@\n\x0b\x61\x63tion_sets\x18\x01 \x03(\x0b\x32+.temporal.omes.kitchen_sink.ClientActionSet\"\xbf\x01\n\x0f\x43lientActionSet\x12\x39\n\x07\x61\x63tions\x18\x01 \x03(\x0b\x32(.temporal.omes.kitchen_sink.ClientAction\x12\x12\n\nconcurrent\x18\x02 \x01(\x08\x12.\n\x0bwait_at_end\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x12-\n%wait_for_current_run_to_finish_at_end\x18\x04 \x01(\x08\"\x98\x01\n\x15WithStartClientAction\x12\x39\n\tdo_signal\x18\x01 \x01(\x0b\x32$.temporal.omes.kitchen_sink.DoSignalH\x00\x12\x39\n\tdo_update\x18\x02 \x01(\x0b\x32$.temporal.omes.kitchen_sink.DoUpdateH\x00\x42\t\n\x07variant\"\xf9\x04\n\x0c\x43lientAction\x12\x39\n\tdo_signal\x18\x01 \x01(\x0b\x32$.temporal.omes.kitchen_sink.DoSignalH\x00\x12\x37\n\x08\x64o_query\x18\x02 \x01(\x0b\x32#.temporal.omes.kitchen_sink.DoQueryH\x00\x12\x39\n\tdo_update\x18\x03 \x01(\x0b\x32$.temporal.omes.kitchen_sink.DoUpdateH\x00\x12\x45\n\x0enested_actions\x18\x04 \x01(\x0b\x32+.temporal.omes.kitchen_sink.ClientActionSetH\x00\x12=\n\x0b\x64o_describe\x18\x05 \x01(\x0b\x32&.temporal.omes.kitchen_sink.DoDescribeH\x00\x12_\n\x1d\x64o_standalone_nexus_operation\x18\x06 \x01(\x0b\x32\x36.temporal.omes.kitchen_sink.DoStandaloneNexusOperationH\x00\x12R\n\x16\x64o_standalone_activity\x18\x07 \x01(\x0b\x32\x30.temporal.omes.kitchen_sink.DoStandaloneActivityH\x00\x12t\n(do_standalone_activity_operator_commands\x18\x08 \x01(\x0b\x32@.temporal.omes.kitchen_sink.DoStandaloneActivityOperatorCommandsH\x00\x42\t\n\x07variant\"b\n\x1a\x44oStandaloneNexusOperation\x12\x44\n\toperation\x18\x01 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteNexusOperation\"[\n\x14\x44oStandaloneActivity\x12\x43\n\x08\x61\x63tivity\x18\x01 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteActivityAction\"\xc5\x02\n$DoStandaloneActivityOperatorCommands\x12\x43\n\x08\x61\x63tivity\x18\x01 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteActivityAction\x12\x62\n\x0c\x63ommand_type\x18\x02 \x01(\x0e\x32L.temporal.omes.kitchen_sink.DoStandaloneActivityOperatorCommands.CommandType\"t\n\x0b\x43ommandType\x12\x1c\n\x18\x43OMMAND_TYPE_UNSPECIFIED\x10\x00\x12\x16\n\x12\x43OMMAND_TYPE_PAUSE\x10\x01\x12\x16\n\x12\x43OMMAND_TYPE_RESET\x10\x02\x12\x17\n\x13\x43OMMAND_TYPE_UPDATE\x10\x03\"\xf1\x02\n\x08\x44oSignal\x12Q\n\x11\x64o_signal_actions\x18\x01 \x01(\x0b\x32\x34.temporal.omes.kitchen_sink.DoSignal.DoSignalActionsH\x00\x12?\n\x06\x63ustom\x18\x02 \x01(\x0b\x32-.temporal.omes.kitchen_sink.HandlerInvocationH\x00\x12\x12\n\nwith_start\x18\x03 \x01(\x08\x1a\xb1\x01\n\x0f\x44oSignalActions\x12;\n\ndo_actions\x18\x01 \x01(\x0b\x32%.temporal.omes.kitchen_sink.ActionSetH\x00\x12\x43\n\x12\x64o_actions_in_main\x18\x02 \x01(\x0b\x32%.temporal.omes.kitchen_sink.ActionSetH\x00\x12\x11\n\tsignal_id\x18\x03 \x01(\x05\x42\t\n\x07variantB\t\n\x07variant\"\x0c\n\nDoDescribe\"\xa9\x01\n\x07\x44oQuery\x12\x38\n\x0creport_state\x18\x01 \x01(\x0b\x32 .temporal.api.common.v1.PayloadsH\x00\x12?\n\x06\x63ustom\x18\x02 \x01(\x0b\x32-.temporal.omes.kitchen_sink.HandlerInvocationH\x00\x12\x18\n\x10\x66\x61ilure_expected\x18\n \x01(\x08\x42\t\n\x07variant\"\xc7\x01\n\x08\x44oUpdate\x12\x41\n\ndo_actions\x18\x01 \x01(\x0b\x32+.temporal.omes.kitchen_sink.DoActionsUpdateH\x00\x12?\n\x06\x63ustom\x18\x02 \x01(\x0b\x32-.temporal.omes.kitchen_sink.HandlerInvocationH\x00\x12\x12\n\nwith_start\x18\x03 \x01(\x08\x12\x18\n\x10\x66\x61ilure_expected\x18\n \x01(\x08\x42\t\n\x07variant\"\x86\x01\n\x0f\x44oActionsUpdate\x12;\n\ndo_actions\x18\x01 \x01(\x0b\x32%.temporal.omes.kitchen_sink.ActionSetH\x00\x12+\n\treject_me\x18\x02 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x42\t\n\x07variant\"P\n\x11HandlerInvocation\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x04\x61rgs\x18\x02 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\"|\n\rWorkflowState\x12?\n\x03kvs\x18\x01 \x03(\x0b\x32\x32.temporal.omes.kitchen_sink.WorkflowState.KvsEntry\x1a*\n\x08KvsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xa8\x01\n\rWorkflowInput\x12>\n\x0finitial_actions\x18\x01 \x03(\x0b\x32%.temporal.omes.kitchen_sink.ActionSet\x12\x1d\n\x15\x65xpected_signal_count\x18\x02 \x01(\x05\x12\x1b\n\x13\x65xpected_signal_ids\x18\x03 \x03(\x05\x12\x1b\n\x13received_signal_ids\x18\x04 \x03(\x05\"T\n\tActionSet\x12\x33\n\x07\x61\x63tions\x18\x01 \x03(\x0b\x32\".temporal.omes.kitchen_sink.Action\x12\x12\n\nconcurrent\x18\x02 \x01(\x08\"\xcc\t\n\x06\x41\x63tion\x12\x38\n\x05timer\x18\x01 \x01(\x0b\x32\'.temporal.omes.kitchen_sink.TimerActionH\x00\x12J\n\rexec_activity\x18\x02 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteActivityActionH\x00\x12U\n\x13\x65xec_child_workflow\x18\x03 \x01(\x0b\x32\x36.temporal.omes.kitchen_sink.ExecuteChildWorkflowActionH\x00\x12N\n\x14\x61wait_workflow_state\x18\x04 \x01(\x0b\x32..temporal.omes.kitchen_sink.AwaitWorkflowStateH\x00\x12\x43\n\x0bsend_signal\x18\x05 \x01(\x0b\x32,.temporal.omes.kitchen_sink.SendSignalActionH\x00\x12K\n\x0f\x63\x61ncel_workflow\x18\x06 \x01(\x0b\x32\x30.temporal.omes.kitchen_sink.CancelWorkflowActionH\x00\x12L\n\x10set_patch_marker\x18\x07 \x01(\x0b\x32\x30.temporal.omes.kitchen_sink.SetPatchMarkerActionH\x00\x12\\\n\x18upsert_search_attributes\x18\x08 \x01(\x0b\x32\x38.temporal.omes.kitchen_sink.UpsertSearchAttributesActionH\x00\x12\x43\n\x0bupsert_memo\x18\t \x01(\x0b\x32,.temporal.omes.kitchen_sink.UpsertMemoActionH\x00\x12G\n\x12set_workflow_state\x18\n \x01(\x0b\x32).temporal.omes.kitchen_sink.WorkflowStateH\x00\x12G\n\rreturn_result\x18\x0b \x01(\x0b\x32..temporal.omes.kitchen_sink.ReturnResultActionH\x00\x12\x45\n\x0creturn_error\x18\x0c \x01(\x0b\x32-.temporal.omes.kitchen_sink.ReturnErrorActionH\x00\x12J\n\x0f\x63ontinue_as_new\x18\r \x01(\x0b\x32/.temporal.omes.kitchen_sink.ContinueAsNewActionH\x00\x12\x42\n\x11nested_action_set\x18\x0e \x01(\x0b\x32%.temporal.omes.kitchen_sink.ActionSetH\x00\x12L\n\x0fnexus_operation\x18\x0f \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteNexusOperationH\x00\x12P\n\x15\x61wait_pending_actions\x18\x11 \x01(\x0b\x32/.temporal.omes.kitchen_sink.AwaitPendingActionsH\x00\x42\t\n\x07variant\"\xd3\x02\n\x0f\x41waitableChoice\x12-\n\x0bwait_finish\x18\x01 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12)\n\x07\x61\x62\x61ndon\x18\x02 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12\x37\n\x15\x63\x61ncel_before_started\x18\x03 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12\x36\n\x14\x63\x61ncel_after_started\x18\x04 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12\x38\n\x16\x63\x61ncel_after_completed\x18\x05 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12.\n\x0cwait_started\x18\x06 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x42\x0b\n\tcondition\"j\n\x0bTimerAction\x12\x14\n\x0cmilliseconds\x18\x01 \x01(\x04\x12\x45\n\x10\x61waitable_choice\x18\x02 \x01(\x0b\x32+.temporal.omes.kitchen_sink.AwaitableChoice\"\xa1\x12\n\x15\x45xecuteActivityAction\x12T\n\x07generic\x18\x01 \x01(\x0b\x32\x41.temporal.omes.kitchen_sink.ExecuteActivityAction.GenericActivityH\x00\x12*\n\x05\x64\x65lay\x18\x02 \x01(\x0b\x32\x19.google.protobuf.DurationH\x00\x12&\n\x04noop\x18\x03 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12X\n\tresources\x18\x0e \x01(\x0b\x32\x43.temporal.omes.kitchen_sink.ExecuteActivityAction.ResourcesActivityH\x00\x12T\n\x07payload\x18\x12 \x01(\x0b\x32\x41.temporal.omes.kitchen_sink.ExecuteActivityAction.PayloadActivityH\x00\x12R\n\x06\x63lient\x18\x13 \x01(\x0b\x32@.temporal.omes.kitchen_sink.ExecuteActivityAction.ClientActivityH\x00\x12\x63\n\x0fretryable_error\x18\x14 \x01(\x0b\x32H.temporal.omes.kitchen_sink.ExecuteActivityAction.RetryableErrorActivityH\x00\x12T\n\x07timeout\x18\x15 \x01(\x0b\x32\x41.temporal.omes.kitchen_sink.ExecuteActivityAction.TimeoutActivityH\x00\x12_\n\theartbeat\x18\x16 \x01(\x0b\x32J.temporal.omes.kitchen_sink.ExecuteActivityAction.HeartbeatTimeoutActivityH\x00\x12\x12\n\ntask_queue\x18\x04 \x01(\t\x12O\n\x07headers\x18\x05 \x03(\x0b\x32>.temporal.omes.kitchen_sink.ExecuteActivityAction.HeadersEntry\x12<\n\x19schedule_to_close_timeout\x18\x06 \x01(\x0b\x32\x19.google.protobuf.Duration\x12<\n\x19schedule_to_start_timeout\x18\x07 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x16start_to_close_timeout\x18\x08 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x34\n\x11heartbeat_timeout\x18\t \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x0cretry_policy\x18\n \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicy\x12*\n\x08is_local\x18\x0b \x01(\x0b\x32\x16.google.protobuf.EmptyH\x01\x12\x43\n\x06remote\x18\x0c \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.RemoteActivityOptionsH\x01\x12\x45\n\x10\x61waitable_choice\x18\r \x01(\x0b\x32+.temporal.omes.kitchen_sink.AwaitableChoice\x12\x32\n\x08priority\x18\x0f \x01(\x0b\x32 .temporal.api.common.v1.Priority\x12\x14\n\x0c\x66\x61irness_key\x18\x10 \x01(\t\x12\x17\n\x0f\x66\x61irness_weight\x18\x11 \x01(\x02\x1aS\n\x0fGenericActivity\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x32\n\targuments\x18\x02 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x1a\x9a\x01\n\x11ResourcesActivity\x12*\n\x07run_for\x18\x01 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x19\n\x11\x62ytes_to_allocate\x18\x02 \x01(\x04\x12$\n\x1c\x63pu_yield_every_n_iterations\x18\x03 \x01(\r\x12\x18\n\x10\x63pu_yield_for_ms\x18\x04 \x01(\r\x1a\x44\n\x0fPayloadActivity\x12\x18\n\x10\x62ytes_to_receive\x18\x01 \x01(\x05\x12\x17\n\x0f\x62ytes_to_return\x18\x02 \x01(\x05\x1aU\n\x0e\x43lientActivity\x12\x43\n\x0f\x63lient_sequence\x18\x01 \x01(\x0b\x32*.temporal.omes.kitchen_sink.ClientSequence\x1a/\n\x16RetryableErrorActivity\x12\x15\n\rfail_attempts\x18\x01 \x01(\x05\x1a\x92\x01\n\x0fTimeoutActivity\x12\x15\n\rfail_attempts\x18\x01 \x01(\x05\x12\x33\n\x10success_duration\x18\x02 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x33\n\x10\x66\x61ilure_duration\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x1a\xd2\x01\n\x18HeartbeatTimeoutActivity\x12\x15\n\rfail_attempts\x18\x01 \x01(\x05\x12\x33\n\x10success_duration\x18\x02 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x33\n\x10\x66\x61ilure_duration\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x35\n\x12heartbeat_interval\x18\x04 \x01(\x0b\x32\x19.google.protobuf.Duration\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x42\x0f\n\ractivity_typeB\n\n\x08locality\"\xad\n\n\x1a\x45xecuteChildWorkflowAction\x12\x11\n\tnamespace\x18\x02 \x01(\t\x12\x13\n\x0bworkflow_id\x18\x03 \x01(\t\x12\x15\n\rworkflow_type\x18\x04 \x01(\t\x12\x12\n\ntask_queue\x18\x05 \x01(\t\x12.\n\x05input\x18\x06 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12=\n\x1aworkflow_execution_timeout\x18\x07 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x37\n\x14workflow_run_timeout\x18\x08 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x38\n\x15workflow_task_timeout\x18\t \x01(\x0b\x32\x19.google.protobuf.Duration\x12J\n\x13parent_close_policy\x18\n \x01(\x0e\x32-.temporal.omes.kitchen_sink.ParentClosePolicy\x12N\n\x18workflow_id_reuse_policy\x18\x0c \x01(\x0e\x32,.temporal.api.enums.v1.WorkflowIdReusePolicy\x12\x39\n\x0cretry_policy\x18\r \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicy\x12\x15\n\rcron_schedule\x18\x0e \x01(\t\x12T\n\x07headers\x18\x0f \x03(\x0b\x32\x43.temporal.omes.kitchen_sink.ExecuteChildWorkflowAction.HeadersEntry\x12N\n\x04memo\x18\x10 \x03(\x0b\x32@.temporal.omes.kitchen_sink.ExecuteChildWorkflowAction.MemoEntry\x12g\n\x11search_attributes\x18\x11 \x03(\x0b\x32L.temporal.omes.kitchen_sink.ExecuteChildWorkflowAction.SearchAttributesEntry\x12T\n\x11\x63\x61ncellation_type\x18\x12 \x01(\x0e\x32\x39.temporal.omes.kitchen_sink.ChildWorkflowCancellationType\x12G\n\x11versioning_intent\x18\x13 \x01(\x0e\x32,.temporal.omes.kitchen_sink.VersioningIntent\x12\x45\n\x10\x61waitable_choice\x18\x14 \x01(\x0b\x32+.temporal.omes.kitchen_sink.AwaitableChoice\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x1aL\n\tMemoEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x1aX\n\x15SearchAttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\"0\n\x12\x41waitWorkflowState\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"\xdf\x02\n\x10SendSignalAction\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x0e\n\x06run_id\x18\x02 \x01(\t\x12\x13\n\x0bsignal_name\x18\x03 \x01(\t\x12-\n\x04\x61rgs\x18\x04 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12J\n\x07headers\x18\x05 \x03(\x0b\x32\x39.temporal.omes.kitchen_sink.SendSignalAction.HeadersEntry\x12\x45\n\x10\x61waitable_choice\x18\x06 \x01(\x0b\x32+.temporal.omes.kitchen_sink.AwaitableChoice\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\";\n\x14\x43\x61ncelWorkflowAction\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x0e\n\x06run_id\x18\x02 \x01(\t\"v\n\x14SetPatchMarkerAction\x12\x10\n\x08patch_id\x18\x01 \x01(\t\x12\x12\n\ndeprecated\x18\x02 \x01(\x08\x12\x38\n\x0cinner_action\x18\x03 \x01(\x0b\x32\".temporal.omes.kitchen_sink.Action\"\xe3\x01\n\x1cUpsertSearchAttributesAction\x12i\n\x11search_attributes\x18\x01 \x03(\x0b\x32N.temporal.omes.kitchen_sink.UpsertSearchAttributesAction.SearchAttributesEntry\x1aX\n\x15SearchAttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\"G\n\x10UpsertMemoAction\x12\x33\n\rupserted_memo\x18\x01 \x01(\x0b\x32\x1c.temporal.api.common.v1.Memo\"J\n\x12ReturnResultAction\x12\x34\n\x0breturn_this\x18\x01 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload\"F\n\x11ReturnErrorAction\x12\x31\n\x07\x66\x61ilure\x18\x01 \x01(\x0b\x32 .temporal.api.failure.v1.Failure\"\xde\x06\n\x13\x43ontinueAsNewAction\x12\x15\n\rworkflow_type\x18\x01 \x01(\t\x12\x12\n\ntask_queue\x18\x02 \x01(\t\x12\x32\n\targuments\x18\x03 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12\x37\n\x14workflow_run_timeout\x18\x04 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x38\n\x15workflow_task_timeout\x18\x05 \x01(\x0b\x32\x19.google.protobuf.Duration\x12G\n\x04memo\x18\x06 \x03(\x0b\x32\x39.temporal.omes.kitchen_sink.ContinueAsNewAction.MemoEntry\x12M\n\x07headers\x18\x07 \x03(\x0b\x32<.temporal.omes.kitchen_sink.ContinueAsNewAction.HeadersEntry\x12`\n\x11search_attributes\x18\x08 \x03(\x0b\x32\x45.temporal.omes.kitchen_sink.ContinueAsNewAction.SearchAttributesEntry\x12\x39\n\x0cretry_policy\x18\t \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicy\x12G\n\x11versioning_intent\x18\n \x01(\x0e\x32,.temporal.omes.kitchen_sink.VersioningIntent\x1aL\n\tMemoEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x1aX\n\x15SearchAttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\"\xd1\x01\n\x15RemoteActivityOptions\x12O\n\x11\x63\x61ncellation_type\x18\x01 \x01(\x0e\x32\x34.temporal.omes.kitchen_sink.ActivityCancellationType\x12\x1e\n\x16\x64o_not_eagerly_execute\x18\x02 \x01(\x08\x12G\n\x11versioning_intent\x18\x03 \x01(\x0e\x32,.temporal.omes.kitchen_sink.VersioningIntent\"\xff\x01\n\x15\x45xecuteNexusOperation\x12\x10\n\x08\x65ndpoint\x18\x01 \x01(\t\x12\x11\n\toperation\x18\x02 \x01(\t\x12@\n\x05input\x18\x03 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.NexusOperationRequest\x12\x45\n\x10\x61waitable_choice\x18\x05 \x01(\x0b\x32+.temporal.omes.kitchen_sink.AwaitableChoice\x12\x38\n\x0f\x65xpected_output\x18\x06 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload\"\xca\x01\n\x15NexusOperationRequest\x12\x0e\n\x04\x65\x63ho\x18\x01 \x01(\tH\x00\x12J\n\x0fworkflow_action\x18\x02 \x01(\x0b\x32/.temporal.omes.kitchen_sink.NexusWorkflowActionH\x00\x12K\n\x0estart_activity\x18\x03 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteActivityActionH\x00\x42\x08\n\x06\x61\x63tion\"\xbb\x01\n\x13NexusWorkflowAction\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x0e\n\x06run_id\x18\x02 \x01(\t\x12L\n\rstart_options\x18\x03 \x01(\x0b\x32\x35.temporal.omes.kitchen_sink.NexusWorkflowStartOptions\x12\'\n\x05start\x18\x04 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x42\x08\n\x06\x61\x63tion\"\xc8\x01\n\x19NexusWorkflowStartOptions\x12\x12\n\ntask_queue\x18\x01 \x01(\t\x12T\n\x1bworkflow_id_conflict_policy\x18\x02 \x01(\x0e\x32/.temporal.api.enums.v1.WorkflowIdConflictPolicy\x12\x41\n\x0eworkflow_input\x18\x03 \x01(\x0b\x32).temporal.omes.kitchen_sink.WorkflowInput\"\x15\n\x13\x41waitPendingActions*\xa4\x01\n\x11ParentClosePolicy\x12#\n\x1fPARENT_CLOSE_POLICY_UNSPECIFIED\x10\x00\x12!\n\x1dPARENT_CLOSE_POLICY_TERMINATE\x10\x01\x12\x1f\n\x1bPARENT_CLOSE_POLICY_ABANDON\x10\x02\x12&\n\"PARENT_CLOSE_POLICY_REQUEST_CANCEL\x10\x03*@\n\x10VersioningIntent\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x0e\n\nCOMPATIBLE\x10\x01\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x02*\xa2\x01\n\x1d\x43hildWorkflowCancellationType\x12\x14\n\x10\x43HILD_WF_ABANDON\x10\x00\x12\x17\n\x13\x43HILD_WF_TRY_CANCEL\x10\x01\x12(\n$CHILD_WF_WAIT_CANCELLATION_COMPLETED\x10\x02\x12(\n$CHILD_WF_WAIT_CANCELLATION_REQUESTED\x10\x03*X\n\x18\x41\x63tivityCancellationType\x12\x0e\n\nTRY_CANCEL\x10\x00\x12\x1f\n\x1bWAIT_CANCELLATION_COMPLETED\x10\x01\x12\x0b\n\x07\x41\x42\x41NDON\x10\x02\x42\x42\n\x10io.temporal.omesZ.github.com/temporalio/omes/loadgen/kitchensinkb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x12kitchen_sink.proto\x12\x1atemporal.omes.kitchen_sink\x1a\x1egoogle/protobuf/duration.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a$temporal/api/common/v1/message.proto\x1a%temporal/api/failure/v1/message.proto\x1a$temporal/api/enums/v1/workflow.proto\"\xe1\x01\n\tTestInput\x12\x41\n\x0eworkflow_input\x18\x01 \x01(\x0b\x32).temporal.omes.kitchen_sink.WorkflowInput\x12\x43\n\x0f\x63lient_sequence\x18\x02 \x01(\x0b\x32*.temporal.omes.kitchen_sink.ClientSequence\x12L\n\x11with_start_action\x18\x03 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.WithStartClientAction\"R\n\x0e\x43lientSequence\x12@\n\x0b\x61\x63tion_sets\x18\x01 \x03(\x0b\x32+.temporal.omes.kitchen_sink.ClientActionSet\"\xbf\x01\n\x0f\x43lientActionSet\x12\x39\n\x07\x61\x63tions\x18\x01 \x03(\x0b\x32(.temporal.omes.kitchen_sink.ClientAction\x12\x12\n\nconcurrent\x18\x02 \x01(\x08\x12.\n\x0bwait_at_end\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x12-\n%wait_for_current_run_to_finish_at_end\x18\x04 \x01(\x08\"\x98\x01\n\x15WithStartClientAction\x12\x39\n\tdo_signal\x18\x01 \x01(\x0b\x32$.temporal.omes.kitchen_sink.DoSignalH\x00\x12\x39\n\tdo_update\x18\x02 \x01(\x0b\x32$.temporal.omes.kitchen_sink.DoUpdateH\x00\x42\t\n\x07variant\"\xf9\x04\n\x0c\x43lientAction\x12\x39\n\tdo_signal\x18\x01 \x01(\x0b\x32$.temporal.omes.kitchen_sink.DoSignalH\x00\x12\x37\n\x08\x64o_query\x18\x02 \x01(\x0b\x32#.temporal.omes.kitchen_sink.DoQueryH\x00\x12\x39\n\tdo_update\x18\x03 \x01(\x0b\x32$.temporal.omes.kitchen_sink.DoUpdateH\x00\x12\x45\n\x0enested_actions\x18\x04 \x01(\x0b\x32+.temporal.omes.kitchen_sink.ClientActionSetH\x00\x12=\n\x0b\x64o_describe\x18\x05 \x01(\x0b\x32&.temporal.omes.kitchen_sink.DoDescribeH\x00\x12_\n\x1d\x64o_standalone_nexus_operation\x18\x06 \x01(\x0b\x32\x36.temporal.omes.kitchen_sink.DoStandaloneNexusOperationH\x00\x12R\n\x16\x64o_standalone_activity\x18\x07 \x01(\x0b\x32\x30.temporal.omes.kitchen_sink.DoStandaloneActivityH\x00\x12t\n(do_standalone_activity_operator_commands\x18\x08 \x01(\x0b\x32@.temporal.omes.kitchen_sink.DoStandaloneActivityOperatorCommandsH\x00\x42\t\n\x07variant\"b\n\x1a\x44oStandaloneNexusOperation\x12\x44\n\toperation\x18\x01 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteNexusOperation\"[\n\x14\x44oStandaloneActivity\x12\x43\n\x08\x61\x63tivity\x18\x01 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteActivityAction\"\xc5\x02\n$DoStandaloneActivityOperatorCommands\x12\x43\n\x08\x61\x63tivity\x18\x01 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteActivityAction\x12\x62\n\x0c\x63ommand_type\x18\x02 \x01(\x0e\x32L.temporal.omes.kitchen_sink.DoStandaloneActivityOperatorCommands.CommandType\"t\n\x0b\x43ommandType\x12\x1c\n\x18\x43OMMAND_TYPE_UNSPECIFIED\x10\x00\x12\x16\n\x12\x43OMMAND_TYPE_PAUSE\x10\x01\x12\x16\n\x12\x43OMMAND_TYPE_RESET\x10\x02\x12\x17\n\x13\x43OMMAND_TYPE_UPDATE\x10\x03\"\xf1\x02\n\x08\x44oSignal\x12Q\n\x11\x64o_signal_actions\x18\x01 \x01(\x0b\x32\x34.temporal.omes.kitchen_sink.DoSignal.DoSignalActionsH\x00\x12?\n\x06\x63ustom\x18\x02 \x01(\x0b\x32-.temporal.omes.kitchen_sink.HandlerInvocationH\x00\x12\x12\n\nwith_start\x18\x03 \x01(\x08\x1a\xb1\x01\n\x0f\x44oSignalActions\x12;\n\ndo_actions\x18\x01 \x01(\x0b\x32%.temporal.omes.kitchen_sink.ActionSetH\x00\x12\x43\n\x12\x64o_actions_in_main\x18\x02 \x01(\x0b\x32%.temporal.omes.kitchen_sink.ActionSetH\x00\x12\x11\n\tsignal_id\x18\x03 \x01(\x05\x42\t\n\x07variantB\t\n\x07variant\"\x0c\n\nDoDescribe\"\xa9\x01\n\x07\x44oQuery\x12\x38\n\x0creport_state\x18\x01 \x01(\x0b\x32 .temporal.api.common.v1.PayloadsH\x00\x12?\n\x06\x63ustom\x18\x02 \x01(\x0b\x32-.temporal.omes.kitchen_sink.HandlerInvocationH\x00\x12\x18\n\x10\x66\x61ilure_expected\x18\n \x01(\x08\x42\t\n\x07variant\"\xc7\x01\n\x08\x44oUpdate\x12\x41\n\ndo_actions\x18\x01 \x01(\x0b\x32+.temporal.omes.kitchen_sink.DoActionsUpdateH\x00\x12?\n\x06\x63ustom\x18\x02 \x01(\x0b\x32-.temporal.omes.kitchen_sink.HandlerInvocationH\x00\x12\x12\n\nwith_start\x18\x03 \x01(\x08\x12\x18\n\x10\x66\x61ilure_expected\x18\n \x01(\x08\x42\t\n\x07variant\"\x86\x01\n\x0f\x44oActionsUpdate\x12;\n\ndo_actions\x18\x01 \x01(\x0b\x32%.temporal.omes.kitchen_sink.ActionSetH\x00\x12+\n\treject_me\x18\x02 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x42\t\n\x07variant\"P\n\x11HandlerInvocation\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x04\x61rgs\x18\x02 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\"|\n\rWorkflowState\x12?\n\x03kvs\x18\x01 \x03(\x0b\x32\x32.temporal.omes.kitchen_sink.WorkflowState.KvsEntry\x1a*\n\x08KvsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xa8\x01\n\rWorkflowInput\x12>\n\x0finitial_actions\x18\x01 \x03(\x0b\x32%.temporal.omes.kitchen_sink.ActionSet\x12\x1d\n\x15\x65xpected_signal_count\x18\x02 \x01(\x05\x12\x1b\n\x13\x65xpected_signal_ids\x18\x03 \x03(\x05\x12\x1b\n\x13received_signal_ids\x18\x04 \x03(\x05\"T\n\tActionSet\x12\x33\n\x07\x61\x63tions\x18\x01 \x03(\x0b\x32\".temporal.omes.kitchen_sink.Action\x12\x12\n\nconcurrent\x18\x02 \x01(\x08\"\xcc\t\n\x06\x41\x63tion\x12\x38\n\x05timer\x18\x01 \x01(\x0b\x32\'.temporal.omes.kitchen_sink.TimerActionH\x00\x12J\n\rexec_activity\x18\x02 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteActivityActionH\x00\x12U\n\x13\x65xec_child_workflow\x18\x03 \x01(\x0b\x32\x36.temporal.omes.kitchen_sink.ExecuteChildWorkflowActionH\x00\x12N\n\x14\x61wait_workflow_state\x18\x04 \x01(\x0b\x32..temporal.omes.kitchen_sink.AwaitWorkflowStateH\x00\x12\x43\n\x0bsend_signal\x18\x05 \x01(\x0b\x32,.temporal.omes.kitchen_sink.SendSignalActionH\x00\x12K\n\x0f\x63\x61ncel_workflow\x18\x06 \x01(\x0b\x32\x30.temporal.omes.kitchen_sink.CancelWorkflowActionH\x00\x12L\n\x10set_patch_marker\x18\x07 \x01(\x0b\x32\x30.temporal.omes.kitchen_sink.SetPatchMarkerActionH\x00\x12\\\n\x18upsert_search_attributes\x18\x08 \x01(\x0b\x32\x38.temporal.omes.kitchen_sink.UpsertSearchAttributesActionH\x00\x12\x43\n\x0bupsert_memo\x18\t \x01(\x0b\x32,.temporal.omes.kitchen_sink.UpsertMemoActionH\x00\x12G\n\x12set_workflow_state\x18\n \x01(\x0b\x32).temporal.omes.kitchen_sink.WorkflowStateH\x00\x12G\n\rreturn_result\x18\x0b \x01(\x0b\x32..temporal.omes.kitchen_sink.ReturnResultActionH\x00\x12\x45\n\x0creturn_error\x18\x0c \x01(\x0b\x32-.temporal.omes.kitchen_sink.ReturnErrorActionH\x00\x12J\n\x0f\x63ontinue_as_new\x18\r \x01(\x0b\x32/.temporal.omes.kitchen_sink.ContinueAsNewActionH\x00\x12\x42\n\x11nested_action_set\x18\x0e \x01(\x0b\x32%.temporal.omes.kitchen_sink.ActionSetH\x00\x12L\n\x0fnexus_operation\x18\x0f \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteNexusOperationH\x00\x12P\n\x15\x61wait_pending_actions\x18\x11 \x01(\x0b\x32/.temporal.omes.kitchen_sink.AwaitPendingActionsH\x00\x42\t\n\x07variant\"\xd3\x02\n\x0f\x41waitableChoice\x12-\n\x0bwait_finish\x18\x01 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12)\n\x07\x61\x62\x61ndon\x18\x02 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12\x37\n\x15\x63\x61ncel_before_started\x18\x03 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12\x36\n\x14\x63\x61ncel_after_started\x18\x04 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12\x38\n\x16\x63\x61ncel_after_completed\x18\x05 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12.\n\x0cwait_started\x18\x06 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x42\x0b\n\tcondition\"j\n\x0bTimerAction\x12\x14\n\x0cmilliseconds\x18\x01 \x01(\x04\x12\x45\n\x10\x61waitable_choice\x18\x02 \x01(\x0b\x32+.temporal.omes.kitchen_sink.AwaitableChoice\"\xa1\x12\n\x15\x45xecuteActivityAction\x12T\n\x07generic\x18\x01 \x01(\x0b\x32\x41.temporal.omes.kitchen_sink.ExecuteActivityAction.GenericActivityH\x00\x12*\n\x05\x64\x65lay\x18\x02 \x01(\x0b\x32\x19.google.protobuf.DurationH\x00\x12&\n\x04noop\x18\x03 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12X\n\tresources\x18\x0e \x01(\x0b\x32\x43.temporal.omes.kitchen_sink.ExecuteActivityAction.ResourcesActivityH\x00\x12T\n\x07payload\x18\x12 \x01(\x0b\x32\x41.temporal.omes.kitchen_sink.ExecuteActivityAction.PayloadActivityH\x00\x12R\n\x06\x63lient\x18\x13 \x01(\x0b\x32@.temporal.omes.kitchen_sink.ExecuteActivityAction.ClientActivityH\x00\x12\x63\n\x0fretryable_error\x18\x14 \x01(\x0b\x32H.temporal.omes.kitchen_sink.ExecuteActivityAction.RetryableErrorActivityH\x00\x12T\n\x07timeout\x18\x15 \x01(\x0b\x32\x41.temporal.omes.kitchen_sink.ExecuteActivityAction.TimeoutActivityH\x00\x12_\n\theartbeat\x18\x16 \x01(\x0b\x32J.temporal.omes.kitchen_sink.ExecuteActivityAction.HeartbeatTimeoutActivityH\x00\x12\x12\n\ntask_queue\x18\x04 \x01(\t\x12O\n\x07headers\x18\x05 \x03(\x0b\x32>.temporal.omes.kitchen_sink.ExecuteActivityAction.HeadersEntry\x12<\n\x19schedule_to_close_timeout\x18\x06 \x01(\x0b\x32\x19.google.protobuf.Duration\x12<\n\x19schedule_to_start_timeout\x18\x07 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x16start_to_close_timeout\x18\x08 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x34\n\x11heartbeat_timeout\x18\t \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x0cretry_policy\x18\n \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicy\x12*\n\x08is_local\x18\x0b \x01(\x0b\x32\x16.google.protobuf.EmptyH\x01\x12\x43\n\x06remote\x18\x0c \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.RemoteActivityOptionsH\x01\x12\x45\n\x10\x61waitable_choice\x18\r \x01(\x0b\x32+.temporal.omes.kitchen_sink.AwaitableChoice\x12\x32\n\x08priority\x18\x0f \x01(\x0b\x32 .temporal.api.common.v1.Priority\x12\x14\n\x0c\x66\x61irness_key\x18\x10 \x01(\t\x12\x17\n\x0f\x66\x61irness_weight\x18\x11 \x01(\x02\x1aS\n\x0fGenericActivity\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x32\n\targuments\x18\x02 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x1a\x9a\x01\n\x11ResourcesActivity\x12*\n\x07run_for\x18\x01 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x19\n\x11\x62ytes_to_allocate\x18\x02 \x01(\x04\x12$\n\x1c\x63pu_yield_every_n_iterations\x18\x03 \x01(\r\x12\x18\n\x10\x63pu_yield_for_ms\x18\x04 \x01(\r\x1a\x44\n\x0fPayloadActivity\x12\x18\n\x10\x62ytes_to_receive\x18\x01 \x01(\x05\x12\x17\n\x0f\x62ytes_to_return\x18\x02 \x01(\x05\x1aU\n\x0e\x43lientActivity\x12\x43\n\x0f\x63lient_sequence\x18\x01 \x01(\x0b\x32*.temporal.omes.kitchen_sink.ClientSequence\x1a/\n\x16RetryableErrorActivity\x12\x15\n\rfail_attempts\x18\x01 \x01(\x05\x1a\x92\x01\n\x0fTimeoutActivity\x12\x15\n\rfail_attempts\x18\x01 \x01(\x05\x12\x33\n\x10success_duration\x18\x02 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x33\n\x10\x66\x61ilure_duration\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x1a\xd2\x01\n\x18HeartbeatTimeoutActivity\x12\x15\n\rfail_attempts\x18\x01 \x01(\x05\x12\x33\n\x10success_duration\x18\x02 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x33\n\x10\x66\x61ilure_duration\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x35\n\x12heartbeat_interval\x18\x04 \x01(\x0b\x32\x19.google.protobuf.Duration\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x42\x0f\n\ractivity_typeB\n\n\x08locality\"\xad\n\n\x1a\x45xecuteChildWorkflowAction\x12\x11\n\tnamespace\x18\x02 \x01(\t\x12\x13\n\x0bworkflow_id\x18\x03 \x01(\t\x12\x15\n\rworkflow_type\x18\x04 \x01(\t\x12\x12\n\ntask_queue\x18\x05 \x01(\t\x12.\n\x05input\x18\x06 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12=\n\x1aworkflow_execution_timeout\x18\x07 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x37\n\x14workflow_run_timeout\x18\x08 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x38\n\x15workflow_task_timeout\x18\t \x01(\x0b\x32\x19.google.protobuf.Duration\x12J\n\x13parent_close_policy\x18\n \x01(\x0e\x32-.temporal.omes.kitchen_sink.ParentClosePolicy\x12N\n\x18workflow_id_reuse_policy\x18\x0c \x01(\x0e\x32,.temporal.api.enums.v1.WorkflowIdReusePolicy\x12\x39\n\x0cretry_policy\x18\r \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicy\x12\x15\n\rcron_schedule\x18\x0e \x01(\t\x12T\n\x07headers\x18\x0f \x03(\x0b\x32\x43.temporal.omes.kitchen_sink.ExecuteChildWorkflowAction.HeadersEntry\x12N\n\x04memo\x18\x10 \x03(\x0b\x32@.temporal.omes.kitchen_sink.ExecuteChildWorkflowAction.MemoEntry\x12g\n\x11search_attributes\x18\x11 \x03(\x0b\x32L.temporal.omes.kitchen_sink.ExecuteChildWorkflowAction.SearchAttributesEntry\x12T\n\x11\x63\x61ncellation_type\x18\x12 \x01(\x0e\x32\x39.temporal.omes.kitchen_sink.ChildWorkflowCancellationType\x12G\n\x11versioning_intent\x18\x13 \x01(\x0e\x32,.temporal.omes.kitchen_sink.VersioningIntent\x12\x45\n\x10\x61waitable_choice\x18\x14 \x01(\x0b\x32+.temporal.omes.kitchen_sink.AwaitableChoice\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x1aL\n\tMemoEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x1aX\n\x15SearchAttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\"0\n\x12\x41waitWorkflowState\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"\xdf\x02\n\x10SendSignalAction\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x0e\n\x06run_id\x18\x02 \x01(\t\x12\x13\n\x0bsignal_name\x18\x03 \x01(\t\x12-\n\x04\x61rgs\x18\x04 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12J\n\x07headers\x18\x05 \x03(\x0b\x32\x39.temporal.omes.kitchen_sink.SendSignalAction.HeadersEntry\x12\x45\n\x10\x61waitable_choice\x18\x06 \x01(\x0b\x32+.temporal.omes.kitchen_sink.AwaitableChoice\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\";\n\x14\x43\x61ncelWorkflowAction\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x0e\n\x06run_id\x18\x02 \x01(\t\"v\n\x14SetPatchMarkerAction\x12\x10\n\x08patch_id\x18\x01 \x01(\t\x12\x12\n\ndeprecated\x18\x02 \x01(\x08\x12\x38\n\x0cinner_action\x18\x03 \x01(\x0b\x32\".temporal.omes.kitchen_sink.Action\"\xe3\x01\n\x1cUpsertSearchAttributesAction\x12i\n\x11search_attributes\x18\x01 \x03(\x0b\x32N.temporal.omes.kitchen_sink.UpsertSearchAttributesAction.SearchAttributesEntry\x1aX\n\x15SearchAttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\"G\n\x10UpsertMemoAction\x12\x33\n\rupserted_memo\x18\x01 \x01(\x0b\x32\x1c.temporal.api.common.v1.Memo\"J\n\x12ReturnResultAction\x12\x34\n\x0breturn_this\x18\x01 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload\"F\n\x11ReturnErrorAction\x12\x31\n\x07\x66\x61ilure\x18\x01 \x01(\x0b\x32 .temporal.api.failure.v1.Failure\"\xde\x06\n\x13\x43ontinueAsNewAction\x12\x15\n\rworkflow_type\x18\x01 \x01(\t\x12\x12\n\ntask_queue\x18\x02 \x01(\t\x12\x32\n\targuments\x18\x03 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12\x37\n\x14workflow_run_timeout\x18\x04 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x38\n\x15workflow_task_timeout\x18\x05 \x01(\x0b\x32\x19.google.protobuf.Duration\x12G\n\x04memo\x18\x06 \x03(\x0b\x32\x39.temporal.omes.kitchen_sink.ContinueAsNewAction.MemoEntry\x12M\n\x07headers\x18\x07 \x03(\x0b\x32<.temporal.omes.kitchen_sink.ContinueAsNewAction.HeadersEntry\x12`\n\x11search_attributes\x18\x08 \x03(\x0b\x32\x45.temporal.omes.kitchen_sink.ContinueAsNewAction.SearchAttributesEntry\x12\x39\n\x0cretry_policy\x18\t \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicy\x12G\n\x11versioning_intent\x18\n \x01(\x0e\x32,.temporal.omes.kitchen_sink.VersioningIntent\x1aL\n\tMemoEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x1aX\n\x15SearchAttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\"\xd1\x01\n\x15RemoteActivityOptions\x12O\n\x11\x63\x61ncellation_type\x18\x01 \x01(\x0e\x32\x34.temporal.omes.kitchen_sink.ActivityCancellationType\x12\x1e\n\x16\x64o_not_eagerly_execute\x18\x02 \x01(\x08\x12G\n\x11versioning_intent\x18\x03 \x01(\x0e\x32,.temporal.omes.kitchen_sink.VersioningIntent\"\xff\x01\n\x15\x45xecuteNexusOperation\x12\x10\n\x08\x65ndpoint\x18\x01 \x01(\t\x12\x11\n\toperation\x18\x02 \x01(\t\x12@\n\x05input\x18\x03 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.NexusOperationRequest\x12\x45\n\x10\x61waitable_choice\x18\x05 \x01(\x0b\x32+.temporal.omes.kitchen_sink.AwaitableChoice\x12\x38\n\x0f\x65xpected_output\x18\x06 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload\"\xca\x01\n\x15NexusOperationRequest\x12\x0e\n\x04\x65\x63ho\x18\x01 \x01(\tH\x00\x12J\n\x0fworkflow_action\x18\x02 \x01(\x0b\x32/.temporal.omes.kitchen_sink.NexusWorkflowActionH\x00\x12K\n\x0estart_activity\x18\x03 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteActivityActionH\x00\x42\x08\n\x06\x61\x63tion\"\xab\x02\n\x13NexusWorkflowAction\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x0e\n\x06run_id\x18\x02 \x01(\t\x12L\n\rstart_options\x18\x03 \x01(\x0b\x32\x35.temporal.omes.kitchen_sink.NexusWorkflowStartOptions\x12\'\n\x05start\x18\x04 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12\x36\n\x06signal\x18\x05 \x01(\x0b\x32$.temporal.omes.kitchen_sink.DoSignalH\x00\x12\x36\n\x06update\x18\x06 \x01(\x0b\x32$.temporal.omes.kitchen_sink.DoUpdateH\x00\x42\x08\n\x06\x61\x63tion\"\xc8\x01\n\x19NexusWorkflowStartOptions\x12\x12\n\ntask_queue\x18\x01 \x01(\t\x12T\n\x1bworkflow_id_conflict_policy\x18\x02 \x01(\x0e\x32/.temporal.api.enums.v1.WorkflowIdConflictPolicy\x12\x41\n\x0eworkflow_input\x18\x03 \x01(\x0b\x32).temporal.omes.kitchen_sink.WorkflowInput\"\x15\n\x13\x41waitPendingActions*\xa4\x01\n\x11ParentClosePolicy\x12#\n\x1fPARENT_CLOSE_POLICY_UNSPECIFIED\x10\x00\x12!\n\x1dPARENT_CLOSE_POLICY_TERMINATE\x10\x01\x12\x1f\n\x1bPARENT_CLOSE_POLICY_ABANDON\x10\x02\x12&\n\"PARENT_CLOSE_POLICY_REQUEST_CANCEL\x10\x03*@\n\x10VersioningIntent\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x0e\n\nCOMPATIBLE\x10\x01\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x02*\xa2\x01\n\x1d\x43hildWorkflowCancellationType\x12\x14\n\x10\x43HILD_WF_ABANDON\x10\x00\x12\x17\n\x13\x43HILD_WF_TRY_CANCEL\x10\x01\x12(\n$CHILD_WF_WAIT_CANCELLATION_COMPLETED\x10\x02\x12(\n$CHILD_WF_WAIT_CANCELLATION_REQUESTED\x10\x03*X\n\x18\x41\x63tivityCancellationType\x12\x0e\n\nTRY_CANCEL\x10\x00\x12\x1f\n\x1bWAIT_CANCELLATION_COMPLETED\x10\x01\x12\x0b\n\x07\x41\x42\x41NDON\x10\x02\x42\x42\n\x10io.temporal.omesZ.github.com/temporalio/omes/loadgen/kitchensinkb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -47,14 +47,14 @@ _globals['_CONTINUEASNEWACTION_HEADERSENTRY']._serialized_options = b'8\001' _globals['_CONTINUEASNEWACTION_SEARCHATTRIBUTESENTRY']._options = None _globals['_CONTINUEASNEWACTION_SEARCHATTRIBUTESENTRY']._serialized_options = b'8\001' - _globals['_PARENTCLOSEPOLICY']._serialized_start=11748 - _globals['_PARENTCLOSEPOLICY']._serialized_end=11912 - _globals['_VERSIONINGINTENT']._serialized_start=11914 - _globals['_VERSIONINGINTENT']._serialized_end=11978 - _globals['_CHILDWORKFLOWCANCELLATIONTYPE']._serialized_start=11981 - _globals['_CHILDWORKFLOWCANCELLATIONTYPE']._serialized_end=12143 - _globals['_ACTIVITYCANCELLATIONTYPE']._serialized_start=12145 - _globals['_ACTIVITYCANCELLATIONTYPE']._serialized_end=12233 + _globals['_PARENTCLOSEPOLICY']._serialized_start=11860 + _globals['_PARENTCLOSEPOLICY']._serialized_end=12024 + _globals['_VERSIONINGINTENT']._serialized_start=12026 + _globals['_VERSIONINGINTENT']._serialized_end=12090 + _globals['_CHILDWORKFLOWCANCELLATIONTYPE']._serialized_start=12093 + _globals['_CHILDWORKFLOWCANCELLATIONTYPE']._serialized_end=12255 + _globals['_ACTIVITYCANCELLATIONTYPE']._serialized_start=12257 + _globals['_ACTIVITYCANCELLATIONTYPE']._serialized_end=12345 _globals['_TESTINPUT']._serialized_start=227 _globals['_TESTINPUT']._serialized_end=452 _globals['_CLIENTSEQUENCE']._serialized_start=454 @@ -162,9 +162,9 @@ _globals['_NEXUSOPERATIONREQUEST']._serialized_start=11127 _globals['_NEXUSOPERATIONREQUEST']._serialized_end=11329 _globals['_NEXUSWORKFLOWACTION']._serialized_start=11332 - _globals['_NEXUSWORKFLOWACTION']._serialized_end=11519 - _globals['_NEXUSWORKFLOWSTARTOPTIONS']._serialized_start=11522 - _globals['_NEXUSWORKFLOWSTARTOPTIONS']._serialized_end=11722 - _globals['_AWAITPENDINGACTIONS']._serialized_start=11724 - _globals['_AWAITPENDINGACTIONS']._serialized_end=11745 + _globals['_NEXUSWORKFLOWACTION']._serialized_end=11631 + _globals['_NEXUSWORKFLOWSTARTOPTIONS']._serialized_start=11634 + _globals['_NEXUSWORKFLOWSTARTOPTIONS']._serialized_end=11834 + _globals['_AWAITPENDINGACTIONS']._serialized_start=11836 + _globals['_AWAITPENDINGACTIONS']._serialized_end=11857 # @@protoc_insertion_point(module_scope) diff --git a/workers/python/protos/kitchen_sink_pb2.pyi b/workers/python/protos/kitchen_sink_pb2.pyi index 771c62a4..7c15e186 100644 --- a/workers/python/protos/kitchen_sink_pb2.pyi +++ b/workers/python/protos/kitchen_sink_pb2.pyi @@ -622,16 +622,20 @@ class NexusOperationRequest(_message.Message): def __init__(self, echo: _Optional[str] = ..., workflow_action: _Optional[_Union[NexusWorkflowAction, _Mapping]] = ..., start_activity: _Optional[_Union[ExecuteActivityAction, _Mapping]] = ...) -> None: ... class NexusWorkflowAction(_message.Message): - __slots__ = ("workflow_id", "run_id", "start_options", "start") + __slots__ = ("workflow_id", "run_id", "start_options", "start", "signal", "update") WORKFLOW_ID_FIELD_NUMBER: _ClassVar[int] RUN_ID_FIELD_NUMBER: _ClassVar[int] START_OPTIONS_FIELD_NUMBER: _ClassVar[int] START_FIELD_NUMBER: _ClassVar[int] + SIGNAL_FIELD_NUMBER: _ClassVar[int] + UPDATE_FIELD_NUMBER: _ClassVar[int] workflow_id: str run_id: str start_options: NexusWorkflowStartOptions start: _empty_pb2.Empty - def __init__(self, workflow_id: _Optional[str] = ..., run_id: _Optional[str] = ..., start_options: _Optional[_Union[NexusWorkflowStartOptions, _Mapping]] = ..., start: _Optional[_Union[_empty_pb2.Empty, _Mapping]] = ...) -> None: ... + signal: DoSignal + update: DoUpdate + def __init__(self, workflow_id: _Optional[str] = ..., run_id: _Optional[str] = ..., start_options: _Optional[_Union[NexusWorkflowStartOptions, _Mapping]] = ..., start: _Optional[_Union[_empty_pb2.Empty, _Mapping]] = ..., signal: _Optional[_Union[DoSignal, _Mapping]] = ..., update: _Optional[_Union[DoUpdate, _Mapping]] = ...) -> None: ... class NexusWorkflowStartOptions(_message.Message): __slots__ = ("task_queue", "workflow_id_conflict_policy", "workflow_input") diff --git a/workers/ruby/protos/kitchen_sink_pb.rb b/workers/ruby/protos/kitchen_sink_pb.rb index 9acaa001..635f4919 100644 --- a/workers/ruby/protos/kitchen_sink_pb.rb +++ b/workers/ruby/protos/kitchen_sink_pb.rb @@ -11,7 +11,7 @@ require 'temporalio/api/enums/v1/workflow' -descriptor_data = "\n\x12kitchen_sink.proto\x12\x1atemporal.omes.kitchen_sink\x1a\x1egoogle/protobuf/duration.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a$temporal/api/common/v1/message.proto\x1a%temporal/api/failure/v1/message.proto\x1a$temporal/api/enums/v1/workflow.proto\"\xe1\x01\n\tTestInput\x12\x41\n\x0eworkflow_input\x18\x01 \x01(\x0b\x32).temporal.omes.kitchen_sink.WorkflowInput\x12\x43\n\x0f\x63lient_sequence\x18\x02 \x01(\x0b\x32*.temporal.omes.kitchen_sink.ClientSequence\x12L\n\x11with_start_action\x18\x03 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.WithStartClientAction\"R\n\x0e\x43lientSequence\x12@\n\x0b\x61\x63tion_sets\x18\x01 \x03(\x0b\x32+.temporal.omes.kitchen_sink.ClientActionSet\"\xbf\x01\n\x0f\x43lientActionSet\x12\x39\n\x07\x61\x63tions\x18\x01 \x03(\x0b\x32(.temporal.omes.kitchen_sink.ClientAction\x12\x12\n\nconcurrent\x18\x02 \x01(\x08\x12.\n\x0bwait_at_end\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x12-\n%wait_for_current_run_to_finish_at_end\x18\x04 \x01(\x08\"\x98\x01\n\x15WithStartClientAction\x12\x39\n\tdo_signal\x18\x01 \x01(\x0b\x32$.temporal.omes.kitchen_sink.DoSignalH\x00\x12\x39\n\tdo_update\x18\x02 \x01(\x0b\x32$.temporal.omes.kitchen_sink.DoUpdateH\x00\x42\t\n\x07variant\"\xf9\x04\n\x0c\x43lientAction\x12\x39\n\tdo_signal\x18\x01 \x01(\x0b\x32$.temporal.omes.kitchen_sink.DoSignalH\x00\x12\x37\n\x08\x64o_query\x18\x02 \x01(\x0b\x32#.temporal.omes.kitchen_sink.DoQueryH\x00\x12\x39\n\tdo_update\x18\x03 \x01(\x0b\x32$.temporal.omes.kitchen_sink.DoUpdateH\x00\x12\x45\n\x0enested_actions\x18\x04 \x01(\x0b\x32+.temporal.omes.kitchen_sink.ClientActionSetH\x00\x12=\n\x0b\x64o_describe\x18\x05 \x01(\x0b\x32&.temporal.omes.kitchen_sink.DoDescribeH\x00\x12_\n\x1d\x64o_standalone_nexus_operation\x18\x06 \x01(\x0b\x32\x36.temporal.omes.kitchen_sink.DoStandaloneNexusOperationH\x00\x12R\n\x16\x64o_standalone_activity\x18\x07 \x01(\x0b\x32\x30.temporal.omes.kitchen_sink.DoStandaloneActivityH\x00\x12t\n(do_standalone_activity_operator_commands\x18\x08 \x01(\x0b\x32@.temporal.omes.kitchen_sink.DoStandaloneActivityOperatorCommandsH\x00\x42\t\n\x07variant\"b\n\x1a\x44oStandaloneNexusOperation\x12\x44\n\toperation\x18\x01 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteNexusOperation\"[\n\x14\x44oStandaloneActivity\x12\x43\n\x08\x61\x63tivity\x18\x01 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteActivityAction\"\xc5\x02\n$DoStandaloneActivityOperatorCommands\x12\x43\n\x08\x61\x63tivity\x18\x01 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteActivityAction\x12\x62\n\x0c\x63ommand_type\x18\x02 \x01(\x0e\x32L.temporal.omes.kitchen_sink.DoStandaloneActivityOperatorCommands.CommandType\"t\n\x0b\x43ommandType\x12\x1c\n\x18\x43OMMAND_TYPE_UNSPECIFIED\x10\x00\x12\x16\n\x12\x43OMMAND_TYPE_PAUSE\x10\x01\x12\x16\n\x12\x43OMMAND_TYPE_RESET\x10\x02\x12\x17\n\x13\x43OMMAND_TYPE_UPDATE\x10\x03\"\xf1\x02\n\x08\x44oSignal\x12Q\n\x11\x64o_signal_actions\x18\x01 \x01(\x0b\x32\x34.temporal.omes.kitchen_sink.DoSignal.DoSignalActionsH\x00\x12?\n\x06\x63ustom\x18\x02 \x01(\x0b\x32-.temporal.omes.kitchen_sink.HandlerInvocationH\x00\x12\x12\n\nwith_start\x18\x03 \x01(\x08\x1a\xb1\x01\n\x0f\x44oSignalActions\x12;\n\ndo_actions\x18\x01 \x01(\x0b\x32%.temporal.omes.kitchen_sink.ActionSetH\x00\x12\x43\n\x12\x64o_actions_in_main\x18\x02 \x01(\x0b\x32%.temporal.omes.kitchen_sink.ActionSetH\x00\x12\x11\n\tsignal_id\x18\x03 \x01(\x05\x42\t\n\x07variantB\t\n\x07variant\"\x0c\n\nDoDescribe\"\xa9\x01\n\x07\x44oQuery\x12\x38\n\x0creport_state\x18\x01 \x01(\x0b\x32 .temporal.api.common.v1.PayloadsH\x00\x12?\n\x06\x63ustom\x18\x02 \x01(\x0b\x32-.temporal.omes.kitchen_sink.HandlerInvocationH\x00\x12\x18\n\x10\x66\x61ilure_expected\x18\n \x01(\x08\x42\t\n\x07variant\"\xc7\x01\n\x08\x44oUpdate\x12\x41\n\ndo_actions\x18\x01 \x01(\x0b\x32+.temporal.omes.kitchen_sink.DoActionsUpdateH\x00\x12?\n\x06\x63ustom\x18\x02 \x01(\x0b\x32-.temporal.omes.kitchen_sink.HandlerInvocationH\x00\x12\x12\n\nwith_start\x18\x03 \x01(\x08\x12\x18\n\x10\x66\x61ilure_expected\x18\n \x01(\x08\x42\t\n\x07variant\"\x86\x01\n\x0f\x44oActionsUpdate\x12;\n\ndo_actions\x18\x01 \x01(\x0b\x32%.temporal.omes.kitchen_sink.ActionSetH\x00\x12+\n\treject_me\x18\x02 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x42\t\n\x07variant\"P\n\x11HandlerInvocation\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x04\x61rgs\x18\x02 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\"|\n\rWorkflowState\x12?\n\x03kvs\x18\x01 \x03(\x0b\x32\x32.temporal.omes.kitchen_sink.WorkflowState.KvsEntry\x1a*\n\x08KvsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xa8\x01\n\rWorkflowInput\x12>\n\x0finitial_actions\x18\x01 \x03(\x0b\x32%.temporal.omes.kitchen_sink.ActionSet\x12\x1d\n\x15\x65xpected_signal_count\x18\x02 \x01(\x05\x12\x1b\n\x13\x65xpected_signal_ids\x18\x03 \x03(\x05\x12\x1b\n\x13received_signal_ids\x18\x04 \x03(\x05\"T\n\tActionSet\x12\x33\n\x07\x61\x63tions\x18\x01 \x03(\x0b\x32\".temporal.omes.kitchen_sink.Action\x12\x12\n\nconcurrent\x18\x02 \x01(\x08\"\xcc\t\n\x06\x41\x63tion\x12\x38\n\x05timer\x18\x01 \x01(\x0b\x32\'.temporal.omes.kitchen_sink.TimerActionH\x00\x12J\n\rexec_activity\x18\x02 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteActivityActionH\x00\x12U\n\x13\x65xec_child_workflow\x18\x03 \x01(\x0b\x32\x36.temporal.omes.kitchen_sink.ExecuteChildWorkflowActionH\x00\x12N\n\x14\x61wait_workflow_state\x18\x04 \x01(\x0b\x32..temporal.omes.kitchen_sink.AwaitWorkflowStateH\x00\x12\x43\n\x0bsend_signal\x18\x05 \x01(\x0b\x32,.temporal.omes.kitchen_sink.SendSignalActionH\x00\x12K\n\x0f\x63\x61ncel_workflow\x18\x06 \x01(\x0b\x32\x30.temporal.omes.kitchen_sink.CancelWorkflowActionH\x00\x12L\n\x10set_patch_marker\x18\x07 \x01(\x0b\x32\x30.temporal.omes.kitchen_sink.SetPatchMarkerActionH\x00\x12\\\n\x18upsert_search_attributes\x18\x08 \x01(\x0b\x32\x38.temporal.omes.kitchen_sink.UpsertSearchAttributesActionH\x00\x12\x43\n\x0bupsert_memo\x18\t \x01(\x0b\x32,.temporal.omes.kitchen_sink.UpsertMemoActionH\x00\x12G\n\x12set_workflow_state\x18\n \x01(\x0b\x32).temporal.omes.kitchen_sink.WorkflowStateH\x00\x12G\n\rreturn_result\x18\x0b \x01(\x0b\x32..temporal.omes.kitchen_sink.ReturnResultActionH\x00\x12\x45\n\x0creturn_error\x18\x0c \x01(\x0b\x32-.temporal.omes.kitchen_sink.ReturnErrorActionH\x00\x12J\n\x0f\x63ontinue_as_new\x18\r \x01(\x0b\x32/.temporal.omes.kitchen_sink.ContinueAsNewActionH\x00\x12\x42\n\x11nested_action_set\x18\x0e \x01(\x0b\x32%.temporal.omes.kitchen_sink.ActionSetH\x00\x12L\n\x0fnexus_operation\x18\x0f \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteNexusOperationH\x00\x12P\n\x15\x61wait_pending_actions\x18\x11 \x01(\x0b\x32/.temporal.omes.kitchen_sink.AwaitPendingActionsH\x00\x42\t\n\x07variant\"\xd3\x02\n\x0f\x41waitableChoice\x12-\n\x0bwait_finish\x18\x01 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12)\n\x07\x61\x62\x61ndon\x18\x02 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12\x37\n\x15\x63\x61ncel_before_started\x18\x03 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12\x36\n\x14\x63\x61ncel_after_started\x18\x04 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12\x38\n\x16\x63\x61ncel_after_completed\x18\x05 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12.\n\x0cwait_started\x18\x06 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x42\x0b\n\tcondition\"j\n\x0bTimerAction\x12\x14\n\x0cmilliseconds\x18\x01 \x01(\x04\x12\x45\n\x10\x61waitable_choice\x18\x02 \x01(\x0b\x32+.temporal.omes.kitchen_sink.AwaitableChoice\"\xa1\x12\n\x15\x45xecuteActivityAction\x12T\n\x07generic\x18\x01 \x01(\x0b\x32\x41.temporal.omes.kitchen_sink.ExecuteActivityAction.GenericActivityH\x00\x12*\n\x05\x64\x65lay\x18\x02 \x01(\x0b\x32\x19.google.protobuf.DurationH\x00\x12&\n\x04noop\x18\x03 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12X\n\tresources\x18\x0e \x01(\x0b\x32\x43.temporal.omes.kitchen_sink.ExecuteActivityAction.ResourcesActivityH\x00\x12T\n\x07payload\x18\x12 \x01(\x0b\x32\x41.temporal.omes.kitchen_sink.ExecuteActivityAction.PayloadActivityH\x00\x12R\n\x06\x63lient\x18\x13 \x01(\x0b\x32@.temporal.omes.kitchen_sink.ExecuteActivityAction.ClientActivityH\x00\x12\x63\n\x0fretryable_error\x18\x14 \x01(\x0b\x32H.temporal.omes.kitchen_sink.ExecuteActivityAction.RetryableErrorActivityH\x00\x12T\n\x07timeout\x18\x15 \x01(\x0b\x32\x41.temporal.omes.kitchen_sink.ExecuteActivityAction.TimeoutActivityH\x00\x12_\n\theartbeat\x18\x16 \x01(\x0b\x32J.temporal.omes.kitchen_sink.ExecuteActivityAction.HeartbeatTimeoutActivityH\x00\x12\x12\n\ntask_queue\x18\x04 \x01(\t\x12O\n\x07headers\x18\x05 \x03(\x0b\x32>.temporal.omes.kitchen_sink.ExecuteActivityAction.HeadersEntry\x12<\n\x19schedule_to_close_timeout\x18\x06 \x01(\x0b\x32\x19.google.protobuf.Duration\x12<\n\x19schedule_to_start_timeout\x18\x07 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x16start_to_close_timeout\x18\x08 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x34\n\x11heartbeat_timeout\x18\t \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x0cretry_policy\x18\n \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicy\x12*\n\x08is_local\x18\x0b \x01(\x0b\x32\x16.google.protobuf.EmptyH\x01\x12\x43\n\x06remote\x18\x0c \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.RemoteActivityOptionsH\x01\x12\x45\n\x10\x61waitable_choice\x18\r \x01(\x0b\x32+.temporal.omes.kitchen_sink.AwaitableChoice\x12\x32\n\x08priority\x18\x0f \x01(\x0b\x32 .temporal.api.common.v1.Priority\x12\x14\n\x0c\x66\x61irness_key\x18\x10 \x01(\t\x12\x17\n\x0f\x66\x61irness_weight\x18\x11 \x01(\x02\x1aS\n\x0fGenericActivity\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x32\n\targuments\x18\x02 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x1a\x9a\x01\n\x11ResourcesActivity\x12*\n\x07run_for\x18\x01 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x19\n\x11\x62ytes_to_allocate\x18\x02 \x01(\x04\x12$\n\x1c\x63pu_yield_every_n_iterations\x18\x03 \x01(\r\x12\x18\n\x10\x63pu_yield_for_ms\x18\x04 \x01(\r\x1a\x44\n\x0fPayloadActivity\x12\x18\n\x10\x62ytes_to_receive\x18\x01 \x01(\x05\x12\x17\n\x0f\x62ytes_to_return\x18\x02 \x01(\x05\x1aU\n\x0e\x43lientActivity\x12\x43\n\x0f\x63lient_sequence\x18\x01 \x01(\x0b\x32*.temporal.omes.kitchen_sink.ClientSequence\x1a/\n\x16RetryableErrorActivity\x12\x15\n\rfail_attempts\x18\x01 \x01(\x05\x1a\x92\x01\n\x0fTimeoutActivity\x12\x15\n\rfail_attempts\x18\x01 \x01(\x05\x12\x33\n\x10success_duration\x18\x02 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x33\n\x10\x66\x61ilure_duration\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x1a\xd2\x01\n\x18HeartbeatTimeoutActivity\x12\x15\n\rfail_attempts\x18\x01 \x01(\x05\x12\x33\n\x10success_duration\x18\x02 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x33\n\x10\x66\x61ilure_duration\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x35\n\x12heartbeat_interval\x18\x04 \x01(\x0b\x32\x19.google.protobuf.Duration\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x42\x0f\n\ractivity_typeB\n\n\x08locality\"\xad\n\n\x1a\x45xecuteChildWorkflowAction\x12\x11\n\tnamespace\x18\x02 \x01(\t\x12\x13\n\x0bworkflow_id\x18\x03 \x01(\t\x12\x15\n\rworkflow_type\x18\x04 \x01(\t\x12\x12\n\ntask_queue\x18\x05 \x01(\t\x12.\n\x05input\x18\x06 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12=\n\x1aworkflow_execution_timeout\x18\x07 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x37\n\x14workflow_run_timeout\x18\x08 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x38\n\x15workflow_task_timeout\x18\t \x01(\x0b\x32\x19.google.protobuf.Duration\x12J\n\x13parent_close_policy\x18\n \x01(\x0e\x32-.temporal.omes.kitchen_sink.ParentClosePolicy\x12N\n\x18workflow_id_reuse_policy\x18\x0c \x01(\x0e\x32,.temporal.api.enums.v1.WorkflowIdReusePolicy\x12\x39\n\x0cretry_policy\x18\r \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicy\x12\x15\n\rcron_schedule\x18\x0e \x01(\t\x12T\n\x07headers\x18\x0f \x03(\x0b\x32\x43.temporal.omes.kitchen_sink.ExecuteChildWorkflowAction.HeadersEntry\x12N\n\x04memo\x18\x10 \x03(\x0b\x32@.temporal.omes.kitchen_sink.ExecuteChildWorkflowAction.MemoEntry\x12g\n\x11search_attributes\x18\x11 \x03(\x0b\x32L.temporal.omes.kitchen_sink.ExecuteChildWorkflowAction.SearchAttributesEntry\x12T\n\x11\x63\x61ncellation_type\x18\x12 \x01(\x0e\x32\x39.temporal.omes.kitchen_sink.ChildWorkflowCancellationType\x12G\n\x11versioning_intent\x18\x13 \x01(\x0e\x32,.temporal.omes.kitchen_sink.VersioningIntent\x12\x45\n\x10\x61waitable_choice\x18\x14 \x01(\x0b\x32+.temporal.omes.kitchen_sink.AwaitableChoice\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x1aL\n\tMemoEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x1aX\n\x15SearchAttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\"0\n\x12\x41waitWorkflowState\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"\xdf\x02\n\x10SendSignalAction\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x0e\n\x06run_id\x18\x02 \x01(\t\x12\x13\n\x0bsignal_name\x18\x03 \x01(\t\x12-\n\x04\x61rgs\x18\x04 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12J\n\x07headers\x18\x05 \x03(\x0b\x32\x39.temporal.omes.kitchen_sink.SendSignalAction.HeadersEntry\x12\x45\n\x10\x61waitable_choice\x18\x06 \x01(\x0b\x32+.temporal.omes.kitchen_sink.AwaitableChoice\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\";\n\x14\x43\x61ncelWorkflowAction\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x0e\n\x06run_id\x18\x02 \x01(\t\"v\n\x14SetPatchMarkerAction\x12\x10\n\x08patch_id\x18\x01 \x01(\t\x12\x12\n\ndeprecated\x18\x02 \x01(\x08\x12\x38\n\x0cinner_action\x18\x03 \x01(\x0b\x32\".temporal.omes.kitchen_sink.Action\"\xe3\x01\n\x1cUpsertSearchAttributesAction\x12i\n\x11search_attributes\x18\x01 \x03(\x0b\x32N.temporal.omes.kitchen_sink.UpsertSearchAttributesAction.SearchAttributesEntry\x1aX\n\x15SearchAttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\"G\n\x10UpsertMemoAction\x12\x33\n\rupserted_memo\x18\x01 \x01(\x0b\x32\x1c.temporal.api.common.v1.Memo\"J\n\x12ReturnResultAction\x12\x34\n\x0breturn_this\x18\x01 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload\"F\n\x11ReturnErrorAction\x12\x31\n\x07\x66\x61ilure\x18\x01 \x01(\x0b\x32 .temporal.api.failure.v1.Failure\"\xde\x06\n\x13\x43ontinueAsNewAction\x12\x15\n\rworkflow_type\x18\x01 \x01(\t\x12\x12\n\ntask_queue\x18\x02 \x01(\t\x12\x32\n\targuments\x18\x03 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12\x37\n\x14workflow_run_timeout\x18\x04 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x38\n\x15workflow_task_timeout\x18\x05 \x01(\x0b\x32\x19.google.protobuf.Duration\x12G\n\x04memo\x18\x06 \x03(\x0b\x32\x39.temporal.omes.kitchen_sink.ContinueAsNewAction.MemoEntry\x12M\n\x07headers\x18\x07 \x03(\x0b\x32<.temporal.omes.kitchen_sink.ContinueAsNewAction.HeadersEntry\x12`\n\x11search_attributes\x18\x08 \x03(\x0b\x32\x45.temporal.omes.kitchen_sink.ContinueAsNewAction.SearchAttributesEntry\x12\x39\n\x0cretry_policy\x18\t \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicy\x12G\n\x11versioning_intent\x18\n \x01(\x0e\x32,.temporal.omes.kitchen_sink.VersioningIntent\x1aL\n\tMemoEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x1aX\n\x15SearchAttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\"\xd1\x01\n\x15RemoteActivityOptions\x12O\n\x11\x63\x61ncellation_type\x18\x01 \x01(\x0e\x32\x34.temporal.omes.kitchen_sink.ActivityCancellationType\x12\x1e\n\x16\x64o_not_eagerly_execute\x18\x02 \x01(\x08\x12G\n\x11versioning_intent\x18\x03 \x01(\x0e\x32,.temporal.omes.kitchen_sink.VersioningIntent\"\xff\x01\n\x15\x45xecuteNexusOperation\x12\x10\n\x08\x65ndpoint\x18\x01 \x01(\t\x12\x11\n\toperation\x18\x02 \x01(\t\x12@\n\x05input\x18\x03 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.NexusOperationRequest\x12\x45\n\x10\x61waitable_choice\x18\x05 \x01(\x0b\x32+.temporal.omes.kitchen_sink.AwaitableChoice\x12\x38\n\x0f\x65xpected_output\x18\x06 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload\"\xca\x01\n\x15NexusOperationRequest\x12\x0e\n\x04\x65\x63ho\x18\x01 \x01(\tH\x00\x12J\n\x0fworkflow_action\x18\x02 \x01(\x0b\x32/.temporal.omes.kitchen_sink.NexusWorkflowActionH\x00\x12K\n\x0estart_activity\x18\x03 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteActivityActionH\x00\x42\x08\n\x06\x61\x63tion\"\xbb\x01\n\x13NexusWorkflowAction\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x0e\n\x06run_id\x18\x02 \x01(\t\x12L\n\rstart_options\x18\x03 \x01(\x0b\x32\x35.temporal.omes.kitchen_sink.NexusWorkflowStartOptions\x12\'\n\x05start\x18\x04 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x42\x08\n\x06\x61\x63tion\"\xc8\x01\n\x19NexusWorkflowStartOptions\x12\x12\n\ntask_queue\x18\x01 \x01(\t\x12T\n\x1bworkflow_id_conflict_policy\x18\x02 \x01(\x0e\x32/.temporal.api.enums.v1.WorkflowIdConflictPolicy\x12\x41\n\x0eworkflow_input\x18\x03 \x01(\x0b\x32).temporal.omes.kitchen_sink.WorkflowInput\"\x15\n\x13\x41waitPendingActions*\xa4\x01\n\x11ParentClosePolicy\x12#\n\x1fPARENT_CLOSE_POLICY_UNSPECIFIED\x10\x00\x12!\n\x1dPARENT_CLOSE_POLICY_TERMINATE\x10\x01\x12\x1f\n\x1bPARENT_CLOSE_POLICY_ABANDON\x10\x02\x12&\n\"PARENT_CLOSE_POLICY_REQUEST_CANCEL\x10\x03*@\n\x10VersioningIntent\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x0e\n\nCOMPATIBLE\x10\x01\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x02*\xa2\x01\n\x1d\x43hildWorkflowCancellationType\x12\x14\n\x10\x43HILD_WF_ABANDON\x10\x00\x12\x17\n\x13\x43HILD_WF_TRY_CANCEL\x10\x01\x12(\n$CHILD_WF_WAIT_CANCELLATION_COMPLETED\x10\x02\x12(\n$CHILD_WF_WAIT_CANCELLATION_REQUESTED\x10\x03*X\n\x18\x41\x63tivityCancellationType\x12\x0e\n\nTRY_CANCEL\x10\x00\x12\x1f\n\x1bWAIT_CANCELLATION_COMPLETED\x10\x01\x12\x0b\n\x07\x41\x42\x41NDON\x10\x02\x42\x42\n\x10io.temporal.omesZ.github.com/temporalio/omes/loadgen/kitchensinkb\x06proto3" +descriptor_data = "\n\x12kitchen_sink.proto\x12\x1atemporal.omes.kitchen_sink\x1a\x1egoogle/protobuf/duration.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a$temporal/api/common/v1/message.proto\x1a%temporal/api/failure/v1/message.proto\x1a$temporal/api/enums/v1/workflow.proto\"\xe1\x01\n\tTestInput\x12\x41\n\x0eworkflow_input\x18\x01 \x01(\x0b\x32).temporal.omes.kitchen_sink.WorkflowInput\x12\x43\n\x0f\x63lient_sequence\x18\x02 \x01(\x0b\x32*.temporal.omes.kitchen_sink.ClientSequence\x12L\n\x11with_start_action\x18\x03 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.WithStartClientAction\"R\n\x0e\x43lientSequence\x12@\n\x0b\x61\x63tion_sets\x18\x01 \x03(\x0b\x32+.temporal.omes.kitchen_sink.ClientActionSet\"\xbf\x01\n\x0f\x43lientActionSet\x12\x39\n\x07\x61\x63tions\x18\x01 \x03(\x0b\x32(.temporal.omes.kitchen_sink.ClientAction\x12\x12\n\nconcurrent\x18\x02 \x01(\x08\x12.\n\x0bwait_at_end\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x12-\n%wait_for_current_run_to_finish_at_end\x18\x04 \x01(\x08\"\x98\x01\n\x15WithStartClientAction\x12\x39\n\tdo_signal\x18\x01 \x01(\x0b\x32$.temporal.omes.kitchen_sink.DoSignalH\x00\x12\x39\n\tdo_update\x18\x02 \x01(\x0b\x32$.temporal.omes.kitchen_sink.DoUpdateH\x00\x42\t\n\x07variant\"\xf9\x04\n\x0c\x43lientAction\x12\x39\n\tdo_signal\x18\x01 \x01(\x0b\x32$.temporal.omes.kitchen_sink.DoSignalH\x00\x12\x37\n\x08\x64o_query\x18\x02 \x01(\x0b\x32#.temporal.omes.kitchen_sink.DoQueryH\x00\x12\x39\n\tdo_update\x18\x03 \x01(\x0b\x32$.temporal.omes.kitchen_sink.DoUpdateH\x00\x12\x45\n\x0enested_actions\x18\x04 \x01(\x0b\x32+.temporal.omes.kitchen_sink.ClientActionSetH\x00\x12=\n\x0b\x64o_describe\x18\x05 \x01(\x0b\x32&.temporal.omes.kitchen_sink.DoDescribeH\x00\x12_\n\x1d\x64o_standalone_nexus_operation\x18\x06 \x01(\x0b\x32\x36.temporal.omes.kitchen_sink.DoStandaloneNexusOperationH\x00\x12R\n\x16\x64o_standalone_activity\x18\x07 \x01(\x0b\x32\x30.temporal.omes.kitchen_sink.DoStandaloneActivityH\x00\x12t\n(do_standalone_activity_operator_commands\x18\x08 \x01(\x0b\x32@.temporal.omes.kitchen_sink.DoStandaloneActivityOperatorCommandsH\x00\x42\t\n\x07variant\"b\n\x1a\x44oStandaloneNexusOperation\x12\x44\n\toperation\x18\x01 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteNexusOperation\"[\n\x14\x44oStandaloneActivity\x12\x43\n\x08\x61\x63tivity\x18\x01 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteActivityAction\"\xc5\x02\n$DoStandaloneActivityOperatorCommands\x12\x43\n\x08\x61\x63tivity\x18\x01 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteActivityAction\x12\x62\n\x0c\x63ommand_type\x18\x02 \x01(\x0e\x32L.temporal.omes.kitchen_sink.DoStandaloneActivityOperatorCommands.CommandType\"t\n\x0b\x43ommandType\x12\x1c\n\x18\x43OMMAND_TYPE_UNSPECIFIED\x10\x00\x12\x16\n\x12\x43OMMAND_TYPE_PAUSE\x10\x01\x12\x16\n\x12\x43OMMAND_TYPE_RESET\x10\x02\x12\x17\n\x13\x43OMMAND_TYPE_UPDATE\x10\x03\"\xf1\x02\n\x08\x44oSignal\x12Q\n\x11\x64o_signal_actions\x18\x01 \x01(\x0b\x32\x34.temporal.omes.kitchen_sink.DoSignal.DoSignalActionsH\x00\x12?\n\x06\x63ustom\x18\x02 \x01(\x0b\x32-.temporal.omes.kitchen_sink.HandlerInvocationH\x00\x12\x12\n\nwith_start\x18\x03 \x01(\x08\x1a\xb1\x01\n\x0f\x44oSignalActions\x12;\n\ndo_actions\x18\x01 \x01(\x0b\x32%.temporal.omes.kitchen_sink.ActionSetH\x00\x12\x43\n\x12\x64o_actions_in_main\x18\x02 \x01(\x0b\x32%.temporal.omes.kitchen_sink.ActionSetH\x00\x12\x11\n\tsignal_id\x18\x03 \x01(\x05\x42\t\n\x07variantB\t\n\x07variant\"\x0c\n\nDoDescribe\"\xa9\x01\n\x07\x44oQuery\x12\x38\n\x0creport_state\x18\x01 \x01(\x0b\x32 .temporal.api.common.v1.PayloadsH\x00\x12?\n\x06\x63ustom\x18\x02 \x01(\x0b\x32-.temporal.omes.kitchen_sink.HandlerInvocationH\x00\x12\x18\n\x10\x66\x61ilure_expected\x18\n \x01(\x08\x42\t\n\x07variant\"\xc7\x01\n\x08\x44oUpdate\x12\x41\n\ndo_actions\x18\x01 \x01(\x0b\x32+.temporal.omes.kitchen_sink.DoActionsUpdateH\x00\x12?\n\x06\x63ustom\x18\x02 \x01(\x0b\x32-.temporal.omes.kitchen_sink.HandlerInvocationH\x00\x12\x12\n\nwith_start\x18\x03 \x01(\x08\x12\x18\n\x10\x66\x61ilure_expected\x18\n \x01(\x08\x42\t\n\x07variant\"\x86\x01\n\x0f\x44oActionsUpdate\x12;\n\ndo_actions\x18\x01 \x01(\x0b\x32%.temporal.omes.kitchen_sink.ActionSetH\x00\x12+\n\treject_me\x18\x02 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x42\t\n\x07variant\"P\n\x11HandlerInvocation\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x04\x61rgs\x18\x02 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\"|\n\rWorkflowState\x12?\n\x03kvs\x18\x01 \x03(\x0b\x32\x32.temporal.omes.kitchen_sink.WorkflowState.KvsEntry\x1a*\n\x08KvsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xa8\x01\n\rWorkflowInput\x12>\n\x0finitial_actions\x18\x01 \x03(\x0b\x32%.temporal.omes.kitchen_sink.ActionSet\x12\x1d\n\x15\x65xpected_signal_count\x18\x02 \x01(\x05\x12\x1b\n\x13\x65xpected_signal_ids\x18\x03 \x03(\x05\x12\x1b\n\x13received_signal_ids\x18\x04 \x03(\x05\"T\n\tActionSet\x12\x33\n\x07\x61\x63tions\x18\x01 \x03(\x0b\x32\".temporal.omes.kitchen_sink.Action\x12\x12\n\nconcurrent\x18\x02 \x01(\x08\"\xcc\t\n\x06\x41\x63tion\x12\x38\n\x05timer\x18\x01 \x01(\x0b\x32\'.temporal.omes.kitchen_sink.TimerActionH\x00\x12J\n\rexec_activity\x18\x02 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteActivityActionH\x00\x12U\n\x13\x65xec_child_workflow\x18\x03 \x01(\x0b\x32\x36.temporal.omes.kitchen_sink.ExecuteChildWorkflowActionH\x00\x12N\n\x14\x61wait_workflow_state\x18\x04 \x01(\x0b\x32..temporal.omes.kitchen_sink.AwaitWorkflowStateH\x00\x12\x43\n\x0bsend_signal\x18\x05 \x01(\x0b\x32,.temporal.omes.kitchen_sink.SendSignalActionH\x00\x12K\n\x0f\x63\x61ncel_workflow\x18\x06 \x01(\x0b\x32\x30.temporal.omes.kitchen_sink.CancelWorkflowActionH\x00\x12L\n\x10set_patch_marker\x18\x07 \x01(\x0b\x32\x30.temporal.omes.kitchen_sink.SetPatchMarkerActionH\x00\x12\\\n\x18upsert_search_attributes\x18\x08 \x01(\x0b\x32\x38.temporal.omes.kitchen_sink.UpsertSearchAttributesActionH\x00\x12\x43\n\x0bupsert_memo\x18\t \x01(\x0b\x32,.temporal.omes.kitchen_sink.UpsertMemoActionH\x00\x12G\n\x12set_workflow_state\x18\n \x01(\x0b\x32).temporal.omes.kitchen_sink.WorkflowStateH\x00\x12G\n\rreturn_result\x18\x0b \x01(\x0b\x32..temporal.omes.kitchen_sink.ReturnResultActionH\x00\x12\x45\n\x0creturn_error\x18\x0c \x01(\x0b\x32-.temporal.omes.kitchen_sink.ReturnErrorActionH\x00\x12J\n\x0f\x63ontinue_as_new\x18\r \x01(\x0b\x32/.temporal.omes.kitchen_sink.ContinueAsNewActionH\x00\x12\x42\n\x11nested_action_set\x18\x0e \x01(\x0b\x32%.temporal.omes.kitchen_sink.ActionSetH\x00\x12L\n\x0fnexus_operation\x18\x0f \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteNexusOperationH\x00\x12P\n\x15\x61wait_pending_actions\x18\x11 \x01(\x0b\x32/.temporal.omes.kitchen_sink.AwaitPendingActionsH\x00\x42\t\n\x07variant\"\xd3\x02\n\x0f\x41waitableChoice\x12-\n\x0bwait_finish\x18\x01 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12)\n\x07\x61\x62\x61ndon\x18\x02 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12\x37\n\x15\x63\x61ncel_before_started\x18\x03 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12\x36\n\x14\x63\x61ncel_after_started\x18\x04 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12\x38\n\x16\x63\x61ncel_after_completed\x18\x05 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12.\n\x0cwait_started\x18\x06 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x42\x0b\n\tcondition\"j\n\x0bTimerAction\x12\x14\n\x0cmilliseconds\x18\x01 \x01(\x04\x12\x45\n\x10\x61waitable_choice\x18\x02 \x01(\x0b\x32+.temporal.omes.kitchen_sink.AwaitableChoice\"\xa1\x12\n\x15\x45xecuteActivityAction\x12T\n\x07generic\x18\x01 \x01(\x0b\x32\x41.temporal.omes.kitchen_sink.ExecuteActivityAction.GenericActivityH\x00\x12*\n\x05\x64\x65lay\x18\x02 \x01(\x0b\x32\x19.google.protobuf.DurationH\x00\x12&\n\x04noop\x18\x03 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12X\n\tresources\x18\x0e \x01(\x0b\x32\x43.temporal.omes.kitchen_sink.ExecuteActivityAction.ResourcesActivityH\x00\x12T\n\x07payload\x18\x12 \x01(\x0b\x32\x41.temporal.omes.kitchen_sink.ExecuteActivityAction.PayloadActivityH\x00\x12R\n\x06\x63lient\x18\x13 \x01(\x0b\x32@.temporal.omes.kitchen_sink.ExecuteActivityAction.ClientActivityH\x00\x12\x63\n\x0fretryable_error\x18\x14 \x01(\x0b\x32H.temporal.omes.kitchen_sink.ExecuteActivityAction.RetryableErrorActivityH\x00\x12T\n\x07timeout\x18\x15 \x01(\x0b\x32\x41.temporal.omes.kitchen_sink.ExecuteActivityAction.TimeoutActivityH\x00\x12_\n\theartbeat\x18\x16 \x01(\x0b\x32J.temporal.omes.kitchen_sink.ExecuteActivityAction.HeartbeatTimeoutActivityH\x00\x12\x12\n\ntask_queue\x18\x04 \x01(\t\x12O\n\x07headers\x18\x05 \x03(\x0b\x32>.temporal.omes.kitchen_sink.ExecuteActivityAction.HeadersEntry\x12<\n\x19schedule_to_close_timeout\x18\x06 \x01(\x0b\x32\x19.google.protobuf.Duration\x12<\n\x19schedule_to_start_timeout\x18\x07 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x16start_to_close_timeout\x18\x08 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x34\n\x11heartbeat_timeout\x18\t \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x39\n\x0cretry_policy\x18\n \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicy\x12*\n\x08is_local\x18\x0b \x01(\x0b\x32\x16.google.protobuf.EmptyH\x01\x12\x43\n\x06remote\x18\x0c \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.RemoteActivityOptionsH\x01\x12\x45\n\x10\x61waitable_choice\x18\r \x01(\x0b\x32+.temporal.omes.kitchen_sink.AwaitableChoice\x12\x32\n\x08priority\x18\x0f \x01(\x0b\x32 .temporal.api.common.v1.Priority\x12\x14\n\x0c\x66\x61irness_key\x18\x10 \x01(\t\x12\x17\n\x0f\x66\x61irness_weight\x18\x11 \x01(\x02\x1aS\n\x0fGenericActivity\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x32\n\targuments\x18\x02 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x1a\x9a\x01\n\x11ResourcesActivity\x12*\n\x07run_for\x18\x01 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x19\n\x11\x62ytes_to_allocate\x18\x02 \x01(\x04\x12$\n\x1c\x63pu_yield_every_n_iterations\x18\x03 \x01(\r\x12\x18\n\x10\x63pu_yield_for_ms\x18\x04 \x01(\r\x1a\x44\n\x0fPayloadActivity\x12\x18\n\x10\x62ytes_to_receive\x18\x01 \x01(\x05\x12\x17\n\x0f\x62ytes_to_return\x18\x02 \x01(\x05\x1aU\n\x0e\x43lientActivity\x12\x43\n\x0f\x63lient_sequence\x18\x01 \x01(\x0b\x32*.temporal.omes.kitchen_sink.ClientSequence\x1a/\n\x16RetryableErrorActivity\x12\x15\n\rfail_attempts\x18\x01 \x01(\x05\x1a\x92\x01\n\x0fTimeoutActivity\x12\x15\n\rfail_attempts\x18\x01 \x01(\x05\x12\x33\n\x10success_duration\x18\x02 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x33\n\x10\x66\x61ilure_duration\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x1a\xd2\x01\n\x18HeartbeatTimeoutActivity\x12\x15\n\rfail_attempts\x18\x01 \x01(\x05\x12\x33\n\x10success_duration\x18\x02 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x33\n\x10\x66\x61ilure_duration\x18\x03 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x35\n\x12heartbeat_interval\x18\x04 \x01(\x0b\x32\x19.google.protobuf.Duration\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x42\x0f\n\ractivity_typeB\n\n\x08locality\"\xad\n\n\x1a\x45xecuteChildWorkflowAction\x12\x11\n\tnamespace\x18\x02 \x01(\t\x12\x13\n\x0bworkflow_id\x18\x03 \x01(\t\x12\x15\n\rworkflow_type\x18\x04 \x01(\t\x12\x12\n\ntask_queue\x18\x05 \x01(\t\x12.\n\x05input\x18\x06 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12=\n\x1aworkflow_execution_timeout\x18\x07 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x37\n\x14workflow_run_timeout\x18\x08 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x38\n\x15workflow_task_timeout\x18\t \x01(\x0b\x32\x19.google.protobuf.Duration\x12J\n\x13parent_close_policy\x18\n \x01(\x0e\x32-.temporal.omes.kitchen_sink.ParentClosePolicy\x12N\n\x18workflow_id_reuse_policy\x18\x0c \x01(\x0e\x32,.temporal.api.enums.v1.WorkflowIdReusePolicy\x12\x39\n\x0cretry_policy\x18\r \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicy\x12\x15\n\rcron_schedule\x18\x0e \x01(\t\x12T\n\x07headers\x18\x0f \x03(\x0b\x32\x43.temporal.omes.kitchen_sink.ExecuteChildWorkflowAction.HeadersEntry\x12N\n\x04memo\x18\x10 \x03(\x0b\x32@.temporal.omes.kitchen_sink.ExecuteChildWorkflowAction.MemoEntry\x12g\n\x11search_attributes\x18\x11 \x03(\x0b\x32L.temporal.omes.kitchen_sink.ExecuteChildWorkflowAction.SearchAttributesEntry\x12T\n\x11\x63\x61ncellation_type\x18\x12 \x01(\x0e\x32\x39.temporal.omes.kitchen_sink.ChildWorkflowCancellationType\x12G\n\x11versioning_intent\x18\x13 \x01(\x0e\x32,.temporal.omes.kitchen_sink.VersioningIntent\x12\x45\n\x10\x61waitable_choice\x18\x14 \x01(\x0b\x32+.temporal.omes.kitchen_sink.AwaitableChoice\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x1aL\n\tMemoEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x1aX\n\x15SearchAttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\"0\n\x12\x41waitWorkflowState\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"\xdf\x02\n\x10SendSignalAction\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x0e\n\x06run_id\x18\x02 \x01(\t\x12\x13\n\x0bsignal_name\x18\x03 \x01(\t\x12-\n\x04\x61rgs\x18\x04 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12J\n\x07headers\x18\x05 \x03(\x0b\x32\x39.temporal.omes.kitchen_sink.SendSignalAction.HeadersEntry\x12\x45\n\x10\x61waitable_choice\x18\x06 \x01(\x0b\x32+.temporal.omes.kitchen_sink.AwaitableChoice\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\";\n\x14\x43\x61ncelWorkflowAction\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x0e\n\x06run_id\x18\x02 \x01(\t\"v\n\x14SetPatchMarkerAction\x12\x10\n\x08patch_id\x18\x01 \x01(\t\x12\x12\n\ndeprecated\x18\x02 \x01(\x08\x12\x38\n\x0cinner_action\x18\x03 \x01(\x0b\x32\".temporal.omes.kitchen_sink.Action\"\xe3\x01\n\x1cUpsertSearchAttributesAction\x12i\n\x11search_attributes\x18\x01 \x03(\x0b\x32N.temporal.omes.kitchen_sink.UpsertSearchAttributesAction.SearchAttributesEntry\x1aX\n\x15SearchAttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\"G\n\x10UpsertMemoAction\x12\x33\n\rupserted_memo\x18\x01 \x01(\x0b\x32\x1c.temporal.api.common.v1.Memo\"J\n\x12ReturnResultAction\x12\x34\n\x0breturn_this\x18\x01 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload\"F\n\x11ReturnErrorAction\x12\x31\n\x07\x66\x61ilure\x18\x01 \x01(\x0b\x32 .temporal.api.failure.v1.Failure\"\xde\x06\n\x13\x43ontinueAsNewAction\x12\x15\n\rworkflow_type\x18\x01 \x01(\t\x12\x12\n\ntask_queue\x18\x02 \x01(\t\x12\x32\n\targuments\x18\x03 \x03(\x0b\x32\x1f.temporal.api.common.v1.Payload\x12\x37\n\x14workflow_run_timeout\x18\x04 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x38\n\x15workflow_task_timeout\x18\x05 \x01(\x0b\x32\x19.google.protobuf.Duration\x12G\n\x04memo\x18\x06 \x03(\x0b\x32\x39.temporal.omes.kitchen_sink.ContinueAsNewAction.MemoEntry\x12M\n\x07headers\x18\x07 \x03(\x0b\x32<.temporal.omes.kitchen_sink.ContinueAsNewAction.HeadersEntry\x12`\n\x11search_attributes\x18\x08 \x03(\x0b\x32\x45.temporal.omes.kitchen_sink.ContinueAsNewAction.SearchAttributesEntry\x12\x39\n\x0cretry_policy\x18\t \x01(\x0b\x32#.temporal.api.common.v1.RetryPolicy\x12G\n\x11versioning_intent\x18\n \x01(\x0e\x32,.temporal.omes.kitchen_sink.VersioningIntent\x1aL\n\tMemoEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x1aO\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\x1aX\n\x15SearchAttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12.\n\x05value\x18\x02 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload:\x02\x38\x01\"\xd1\x01\n\x15RemoteActivityOptions\x12O\n\x11\x63\x61ncellation_type\x18\x01 \x01(\x0e\x32\x34.temporal.omes.kitchen_sink.ActivityCancellationType\x12\x1e\n\x16\x64o_not_eagerly_execute\x18\x02 \x01(\x08\x12G\n\x11versioning_intent\x18\x03 \x01(\x0e\x32,.temporal.omes.kitchen_sink.VersioningIntent\"\xff\x01\n\x15\x45xecuteNexusOperation\x12\x10\n\x08\x65ndpoint\x18\x01 \x01(\t\x12\x11\n\toperation\x18\x02 \x01(\t\x12@\n\x05input\x18\x03 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.NexusOperationRequest\x12\x45\n\x10\x61waitable_choice\x18\x05 \x01(\x0b\x32+.temporal.omes.kitchen_sink.AwaitableChoice\x12\x38\n\x0f\x65xpected_output\x18\x06 \x01(\x0b\x32\x1f.temporal.api.common.v1.Payload\"\xca\x01\n\x15NexusOperationRequest\x12\x0e\n\x04\x65\x63ho\x18\x01 \x01(\tH\x00\x12J\n\x0fworkflow_action\x18\x02 \x01(\x0b\x32/.temporal.omes.kitchen_sink.NexusWorkflowActionH\x00\x12K\n\x0estart_activity\x18\x03 \x01(\x0b\x32\x31.temporal.omes.kitchen_sink.ExecuteActivityActionH\x00\x42\x08\n\x06\x61\x63tion\"\xab\x02\n\x13NexusWorkflowAction\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x0e\n\x06run_id\x18\x02 \x01(\t\x12L\n\rstart_options\x18\x03 \x01(\x0b\x32\x35.temporal.omes.kitchen_sink.NexusWorkflowStartOptions\x12\'\n\x05start\x18\x04 \x01(\x0b\x32\x16.google.protobuf.EmptyH\x00\x12\x36\n\x06signal\x18\x05 \x01(\x0b\x32$.temporal.omes.kitchen_sink.DoSignalH\x00\x12\x36\n\x06update\x18\x06 \x01(\x0b\x32$.temporal.omes.kitchen_sink.DoUpdateH\x00\x42\x08\n\x06\x61\x63tion\"\xc8\x01\n\x19NexusWorkflowStartOptions\x12\x12\n\ntask_queue\x18\x01 \x01(\t\x12T\n\x1bworkflow_id_conflict_policy\x18\x02 \x01(\x0e\x32/.temporal.api.enums.v1.WorkflowIdConflictPolicy\x12\x41\n\x0eworkflow_input\x18\x03 \x01(\x0b\x32).temporal.omes.kitchen_sink.WorkflowInput\"\x15\n\x13\x41waitPendingActions*\xa4\x01\n\x11ParentClosePolicy\x12#\n\x1fPARENT_CLOSE_POLICY_UNSPECIFIED\x10\x00\x12!\n\x1dPARENT_CLOSE_POLICY_TERMINATE\x10\x01\x12\x1f\n\x1bPARENT_CLOSE_POLICY_ABANDON\x10\x02\x12&\n\"PARENT_CLOSE_POLICY_REQUEST_CANCEL\x10\x03*@\n\x10VersioningIntent\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x0e\n\nCOMPATIBLE\x10\x01\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x02*\xa2\x01\n\x1d\x43hildWorkflowCancellationType\x12\x14\n\x10\x43HILD_WF_ABANDON\x10\x00\x12\x17\n\x13\x43HILD_WF_TRY_CANCEL\x10\x01\x12(\n$CHILD_WF_WAIT_CANCELLATION_COMPLETED\x10\x02\x12(\n$CHILD_WF_WAIT_CANCELLATION_REQUESTED\x10\x03*X\n\x18\x41\x63tivityCancellationType\x12\x0e\n\nTRY_CANCEL\x10\x00\x12\x1f\n\x1bWAIT_CANCELLATION_COMPLETED\x10\x01\x12\x0b\n\x07\x41\x42\x41NDON\x10\x02\x42\x42\n\x10io.temporal.omesZ.github.com/temporalio/omes/loadgen/kitchensinkb\x06proto3" pool = Google::Protobuf::DescriptorPool.generated_pool From 4c3f8b60955d777afa80b53a187ba012e8ef1676 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 7 Sep 2026 14:06:40 -0700 Subject: [PATCH 02/18] Make Nexus messages complete target workflows --- loadgen/kitchen_sink_executor_test.go | 19 +++++++++++++++--- loadgen/kitchensink/helpers.go | 28 +++++++-------------------- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/loadgen/kitchen_sink_executor_test.go b/loadgen/kitchen_sink_executor_test.go index e8266eeb..5fcae7e5 100644 --- a/loadgen/kitchen_sink_executor_test.go +++ b/loadgen/kitchen_sink_executor_test.go @@ -1218,7 +1218,13 @@ func TestKitchenSink(t *testing.T) { testInput: &TestInput{WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( NewNexusWorkflowTargetSequence("", "nexus-signal-target", nil, NewNexusOperationAction("", - NexusSignalWorkflowRequest("nexus-signal-target", "", &DoSignal{}, nil), + NexusSignalWorkflowRequest("nexus-signal-target", "", &DoSignal{ + Variant: &DoSignal_DoSignalActions_{DoSignalActions: &DoSignal_DoSignalActions{ + Variant: &DoSignal_DoSignalActions_DoActions{DoActions: SingleActionSet( + NewSetWorkflowStateAction("status", "done"), + )}, + }}, + }, nil), ConvertToPayload("nexus-signal-target"), WaitFinishChoice(), ), @@ -1233,8 +1239,14 @@ func TestKitchenSink(t *testing.T) { testInput: &TestInput{WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( NewNexusWorkflowTargetSequence("", "nexus-sws-target", NewNexusOperationAction("", - NexusSignalWorkflowRequest("nexus-sws-target", "", &DoSignal{WithStart: true}, - &NexusWorkflowStartOptions{WorkflowInput: &WorkflowInput{}}), + NexusSignalWorkflowRequest("nexus-sws-target", "", &DoSignal{ + Variant: &DoSignal_DoSignalActions_{DoSignalActions: &DoSignal_DoSignalActions{ + Variant: &DoSignal_DoSignalActions_DoActionsInMain{DoActionsInMain: SingleActionSet( + NewEmptyReturnResultAction(), + )}, + }}, + WithStart: true, + }, &NexusWorkflowStartOptions{WorkflowInput: &WorkflowInput{}}), ConvertToPayload("nexus-sws-target"), WaitFinishChoice(), ), @@ -1252,6 +1264,7 @@ func TestKitchenSink(t *testing.T) { NexusUpdateWorkflowRequest("nexus-update-target", "", &DoUpdate{ Variant: &DoUpdate_DoActions{DoActions: &DoActionsUpdate{ Variant: &DoActionsUpdate_DoActions{DoActions: SingleActionSet( + NewSetWorkflowStateAction("status", "done"), NewNexusUpdateResultAction("nexus-update-target"), )}, }}, diff --git a/loadgen/kitchensink/helpers.go b/loadgen/kitchensink/helpers.go index 101c9935..90567ca9 100644 --- a/loadgen/kitchensink/helpers.go +++ b/loadgen/kitchensink/helpers.go @@ -149,7 +149,7 @@ func NewNexusOperationAction( } // NewNexusWorkflowTargetSequence starts one kitchenSink workflow, applies the -// provided actions to it, then completes the target and awaits pending actions. +// provided actions to it, then awaits pending actions. func NewNexusWorkflowTargetSequence(endpoint string, workflowID string, startAction *Action, actions ...*Action) *Action { if startAction == nil { startAction = NewNexusOperationAction(endpoint, @@ -157,7 +157,10 @@ func NewNexusWorkflowTargetSequence(endpoint string, workflowID string, startAct Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ WorkflowId: workflowID, StartOptions: &NexusWorkflowStartOptions{ - WorkflowInput: &WorkflowInput{}, + WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( + NewAwaitWorkflowStateAction("status", "done"), + NewEmptyReturnResultAction(), + )}, }, Action: &NexusWorkflowAction_Start{Start: &emptypb.Empty{}}, }}, @@ -166,18 +169,10 @@ func NewNexusWorkflowTargetSequence(endpoint string, workflowID string, startAct &AwaitableChoice{Condition: &AwaitableChoice_WaitStarted{WaitStarted: &emptypb.Empty{}}}, ) } - sequence := make([]*Action, 0, len(actions)+3) + sequence := make([]*Action, 0, len(actions)+2) sequence = append(sequence, startAction) sequence = append(sequence, actions...) - sequence = append(sequence, - &Action{Variant: &Action_SendSignal{SendSignal: &SendSignalAction{ - WorkflowId: workflowID, - SignalName: "do_actions_signal", - Args: []*common.Payload{ConvertToPayload(NewReturnResultSignal())}, - AwaitableChoice: WaitFinishChoice(), - }}}, - &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}, - ) + sequence = append(sequence, &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}) return &Action{Variant: &Action_NestedActionSet{NestedActionSet: &ActionSet{Actions: sequence}}} } @@ -187,15 +182,6 @@ func WaitFinishChoice() *AwaitableChoice { Condition: &AwaitableChoice_WaitFinish{WaitFinish: &emptypb.Empty{}}, } } - -// NewReturnResultSignal completes a kitchenSink workflow through do_actions_signal. -func NewReturnResultSignal() *DoSignal_DoSignalActions { - return &DoSignal_DoSignalActions{ - Variant: &DoSignal_DoSignalActions_DoActionsInMain{ - DoActionsInMain: SingleActionSet(NewEmptyReturnResultAction()), - }, - } -} func ClientActivity(clientSeq *ClientSequence, factory ActionFactory[ExecuteActivityAction]) *Action { activity := &ExecuteActivityAction{ ActivityType: &ExecuteActivityAction_Client{ From 44dad77d6606766309361c3f7922712f9d58fb75 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 7 Sep 2026 18:15:36 -0700 Subject: [PATCH 03/18] Update kitchen_sink.go --- workers/go/workerlib/kitchensink/kitchen_sink.go | 1 + 1 file changed, 1 insertion(+) diff --git a/workers/go/workerlib/kitchensink/kitchen_sink.go b/workers/go/workerlib/kitchensink/kitchen_sink.go index 2acf941d..5b7ba8bf 100644 --- a/workers/go/workerlib/kitchensink/kitchen_sink.go +++ b/workers/go/workerlib/kitchensink/kitchen_sink.go @@ -708,6 +708,7 @@ func signalWorkflowNexusOperation( } return temporalnexus.NewSyncResult(kitchensink.ConvertToPayload(input.GetWorkflowId())), nil } + func updateWorkflowNexusOperation( ctx context.Context, nc temporalnexus.NexusClient, From ea89cfe827bb9f1616a2f09d75f54349070c44bc Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 7 Sep 2026 18:56:19 -0700 Subject: [PATCH 04/18] Simplify Nexus workflow messaging implementation --- internal/workertest/historyrequire.go | 11 +- loadgen/kitchen_sink_executor_test.go | 49 ++++- loadgen/kitchensink/helpers.go | 28 --- .../go/workerlib/kitchensink/kitchen_sink.go | 197 ++++++++---------- 4 files changed, 135 insertions(+), 150 deletions(-) diff --git a/internal/workertest/historyrequire.go b/internal/workertest/historyrequire.go index 4709adde..ed529744 100644 --- a/internal/workertest/historyrequire.go +++ b/internal/workertest/historyrequire.go @@ -5,6 +5,7 @@ import ( "fmt" "maps" "reflect" + "slices" "strings" "testing" @@ -282,15 +283,7 @@ func looselyEqual(x, y any) bool { // Compare element-wise so each expected element can be a partial map. The // lengths must match, but not every field of each element. yList, ok := y.([]any) - if !ok || len(yList) != len(x) { - return false - } - for i, yv := range yList { - if !looselyEqual(x[i], yv) { - return false - } - } - return true + return ok && slices.EqualFunc(x, yList, looselyEqual) } return reflect.DeepEqual(x, y) } diff --git a/loadgen/kitchen_sink_executor_test.go b/loadgen/kitchen_sink_executor_test.go index 5fcae7e5..6e01603d 100644 --- a/loadgen/kitchen_sink_executor_test.go +++ b/loadgen/kitchen_sink_executor_test.go @@ -1213,10 +1213,28 @@ func TestKitchenSink(t *testing.T) { DoStandaloneActivityOperatorCommands_COMMAND_TYPE_RESET), standaloneActivityOperatorCommandsTestCase("Update", DoStandaloneActivityOperatorCommands_COMMAND_TYPE_UPDATE), + // These tests start one kitchenSink workflow, apply an action to it, then + // await pending actions. { name: "NexusOperation/Sync/Signal", testInput: &TestInput{WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( - NewNexusWorkflowTargetSequence("", "nexus-signal-target", nil, + &Action{Variant: &Action_NestedActionSet{NestedActionSet: &ActionSet{Actions: []*Action{ + NewNexusOperationAction("", + &NexusOperationRequest{ + Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ + WorkflowId: "nexus-signal-target", + StartOptions: &NexusWorkflowStartOptions{ + WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( + NewAwaitWorkflowStateAction("status", "done"), + NewEmptyReturnResultAction(), + )}, + }, + Action: &NexusWorkflowAction_Start{Start: &emptypb.Empty{}}, + }}, + }, + nil, + &AwaitableChoice{Condition: &AwaitableChoice_WaitStarted{WaitStarted: &emptypb.Empty{}}}, + ), NewNexusOperationAction("", NexusSignalWorkflowRequest("nexus-signal-target", "", &DoSignal{ Variant: &DoSignal_DoSignalActions_{DoSignalActions: &DoSignal_DoSignalActions{ @@ -1228,7 +1246,8 @@ func TestKitchenSink(t *testing.T) { ConvertToPayload("nexus-signal-target"), WaitFinishChoice(), ), - ), + &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}, + }}}}, )}}, historyMatcher: PartialHistoryMatcher(` NexusOperationCompleted {"links":[{"workflowEvent":{"workflowId":"nexus-signal-target","requestIdRef":{"eventType":"EVENT_TYPE_WORKFLOW_EXECUTION_SIGNALED"}}}]}`), @@ -1237,7 +1256,7 @@ func TestKitchenSink(t *testing.T) { { name: "NexusOperation/Sync/SignalWithStart", testInput: &TestInput{WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( - NewNexusWorkflowTargetSequence("", "nexus-sws-target", + &Action{Variant: &Action_NestedActionSet{NestedActionSet: &ActionSet{Actions: []*Action{ NewNexusOperationAction("", NexusSignalWorkflowRequest("nexus-sws-target", "", &DoSignal{ Variant: &DoSignal_DoSignalActions_{DoSignalActions: &DoSignal_DoSignalActions{ @@ -1250,7 +1269,8 @@ func TestKitchenSink(t *testing.T) { ConvertToPayload("nexus-sws-target"), WaitFinishChoice(), ), - ), + &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}, + }}}}, )}}, historyMatcher: PartialHistoryMatcher(` NexusOperationCompleted {"links":[{"workflowEvent":{"workflowId":"nexus-sws-target","requestIdRef":{"eventType":"EVENT_TYPE_WORKFLOW_EXECUTION_SIGNALED"}}}]}`), @@ -1259,7 +1279,23 @@ func TestKitchenSink(t *testing.T) { { name: "NexusOperation/Async/Update", testInput: &TestInput{WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( - NewNexusWorkflowTargetSequence("", "nexus-update-target", nil, + &Action{Variant: &Action_NestedActionSet{NestedActionSet: &ActionSet{Actions: []*Action{ + NewNexusOperationAction("", + &NexusOperationRequest{ + Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ + WorkflowId: "nexus-update-target", + StartOptions: &NexusWorkflowStartOptions{ + WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( + NewAwaitWorkflowStateAction("status", "done"), + NewEmptyReturnResultAction(), + )}, + }, + Action: &NexusWorkflowAction_Start{Start: &emptypb.Empty{}}, + }}, + }, + nil, + &AwaitableChoice{Condition: &AwaitableChoice_WaitStarted{WaitStarted: &emptypb.Empty{}}}, + ), NewNexusOperationAction("", NexusUpdateWorkflowRequest("nexus-update-target", "", &DoUpdate{ Variant: &DoUpdate_DoActions{DoActions: &DoActionsUpdate{ @@ -1272,7 +1308,8 @@ func TestKitchenSink(t *testing.T) { ConvertToPayload("nexus-update-target"), WaitFinishChoice(), ), - ), + &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}, + }}}}, )}}, historyMatcher: PartialHistoryMatcher(` NexusOperationCompleted {"links":[{"workflowEvent":{"workflowId":"nexus-update-target","requestIdRef":{"eventType":"EVENT_TYPE_WORKFLOW_EXECUTION_UPDATE_ACCEPTED"}}}]}`), diff --git a/loadgen/kitchensink/helpers.go b/loadgen/kitchensink/helpers.go index 90567ca9..d5efc721 100644 --- a/loadgen/kitchensink/helpers.go +++ b/loadgen/kitchensink/helpers.go @@ -148,34 +148,6 @@ func NewNexusOperationAction( } } -// NewNexusWorkflowTargetSequence starts one kitchenSink workflow, applies the -// provided actions to it, then awaits pending actions. -func NewNexusWorkflowTargetSequence(endpoint string, workflowID string, startAction *Action, actions ...*Action) *Action { - if startAction == nil { - startAction = NewNexusOperationAction(endpoint, - &NexusOperationRequest{ - Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ - WorkflowId: workflowID, - StartOptions: &NexusWorkflowStartOptions{ - WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( - NewAwaitWorkflowStateAction("status", "done"), - NewEmptyReturnResultAction(), - )}, - }, - Action: &NexusWorkflowAction_Start{Start: &emptypb.Empty{}}, - }}, - }, - nil, - &AwaitableChoice{Condition: &AwaitableChoice_WaitStarted{WaitStarted: &emptypb.Empty{}}}, - ) - } - sequence := make([]*Action, 0, len(actions)+2) - sequence = append(sequence, startAction) - sequence = append(sequence, actions...) - sequence = append(sequence, &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}) - return &Action{Variant: &Action_NestedActionSet{NestedActionSet: &ActionSet{Actions: sequence}}} -} - // WaitFinishChoice awaits an operation through to completion. func WaitFinishChoice() *AwaitableChoice { return &AwaitableChoice{ diff --git a/workers/go/workerlib/kitchensink/kitchen_sink.go b/workers/go/workerlib/kitchensink/kitchen_sink.go index 5b7ba8bf..79fb38d9 100644 --- a/workers/go/workerlib/kitchensink/kitchen_sink.go +++ b/workers/go/workerlib/kitchensink/kitchen_sink.go @@ -643,9 +643,97 @@ func startNexusOperation( cmp.Or(startOptions.GetWorkflowInput(), &kitchensink.WorkflowInput{}), ) case *kitchensink.NexusWorkflowAction_Signal: - return signalWorkflowNexusOperation(ctx, workflowAction) + var result temporalnexus.TemporalOperationResult[*common.Payload] + if workflowAction.GetWorkflowId() == "" { + return result, nexus.HandlerErrorf( + nexus.HandlerErrorTypeBadRequest, "signal target must include a workflow ID") + } + + signal := workflowAction.GetSignal() + signalName := "do_actions_signal" + // Default to an empty action set so an operation can exercise signal + // delivery without requiring the target workflow to run another action. + var signalArg any = &kitchensink.DoSignal_DoSignalActions{ + Variant: &kitchensink.DoSignal_DoSignalActions_DoActions{ + DoActions: kitchensink.SingleActionSet(), + }, + } + if custom := signal.GetCustom(); custom != nil { + signalName = custom.GetName() + signalArg = custom.GetArgs() + } else if doActions := signal.GetDoSignalActions(); doActions != nil { + signalArg = doActions + } + + if signal.GetWithStart() { + startOptions := client.StartWorkflowOptions{ + ID: workflowAction.GetWorkflowId(), + TaskQueue: workflowAction.GetStartOptions().GetTaskQueue(), + WorkflowExecutionTimeout: 60 * time.Minute, + WorkflowIDConflictPolicy: enumspb.WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING, + } + if startOptions.TaskQueue == "" { + // Default to the task queue handling this Nexus request. + startOptions.TaskQueue = temporalnexus.GetOperationInfo(ctx).TaskQueue + } + workflowInput := cmp.Or( + workflowAction.GetStartOptions().GetWorkflowInput(), &kitchensink.WorkflowInput{}) + run, err := temporalnexus.GetClient(ctx).SignalWithStartWorkflow( + ctx, workflowAction.GetWorkflowId(), signalName, signalArg, startOptions, + KitchenSinkWorkflow, workflowInput) + if err != nil { + return result, nexusOutboundError("SignalWithStartWorkflow", err) + } + return temporalnexus.NewSyncResult(kitchensink.ConvertToPayload(run.GetID())), nil + } + + err := temporalnexus.GetClient(ctx).SignalWorkflow( + ctx, workflowAction.GetWorkflowId(), workflowAction.GetRunId(), signalName, signalArg) + if err != nil { + return result, nexusOutboundError("SignalWorkflow", err) + } + return temporalnexus.NewSyncResult( + kitchensink.ConvertToPayload(workflowAction.GetWorkflowId())), nil case *kitchensink.NexusWorkflowAction_Update: - return updateWorkflowNexusOperation(ctx, nc, workflowAction) + var result temporalnexus.TemporalOperationResult[*common.Payload] + if workflowAction.GetWorkflowId() == "" { + return result, nexus.HandlerErrorf( + nexus.HandlerErrorTypeBadRequest, "update target must include a workflow ID") + } + if workflowAction.GetUpdate().GetWithStart() { + return result, nexus.HandlerErrorf( + nexus.HandlerErrorTypeBadRequest, + "update-with-start is not supported by this Nexus operation") + } + + updateName := "do_actions_update" + var args []any + if custom := workflowAction.GetUpdate().GetCustom(); custom != nil { + updateName = custom.GetName() + args = []any{custom.GetArgs()} + } else if update := workflowAction.GetUpdate().GetDoActions(); update != nil { + args = []any{update} + } else { + break + } + + // UpdateID is deliberately left unset: StartUpdateWorkflow derives it from the + // Nexus request ID, so a retried Nexus task attaches to the original update + // rather than starting a second one. + result, err := temporalnexus.StartUpdateWorkflow[*common.Payload](ctx, nc, client.UpdateWorkflowOptions{ + WorkflowID: workflowAction.GetWorkflowId(), + RunID: workflowAction.GetRunId(), + UpdateName: updateName, + Args: args, + // Accepted is the only stage a Nexus-backed update supports: the operation + // goes async once the update is accepted, and the update's result reaches + // the caller later through the operation's completion callback. + WaitForStage: client.WorkflowUpdateStageAccepted, + }) + if err != nil { + return result, nexusOutboundError("UpdateWorkflow", err) + } + return result, nil } case *kitchensink.NexusOperationRequest_StartActivity: return startStandaloneActivityNexusOperation(ctx, nc, action.StartActivity, opts) @@ -654,111 +742,6 @@ func startNexusOperation( nexus.HandlerErrorTypeBadRequest, "Nexus operation request has no supported action set") } -func signalWorkflowNexusOperation( - ctx context.Context, - input *kitchensink.NexusWorkflowAction, -) (temporalnexus.TemporalOperationResult[*common.Payload], error) { - var result temporalnexus.TemporalOperationResult[*common.Payload] - if input.GetWorkflowId() == "" { - return result, nexus.HandlerErrorf( - nexus.HandlerErrorTypeBadRequest, "signal target must include a workflow ID") - } - - signal := input.GetSignal() - signalName := "do_actions_signal" - // Default to an empty action set so an operation can exercise signal - // delivery without requiring the target workflow to run another action. - var signalArg any = &kitchensink.DoSignal_DoSignalActions{ - Variant: &kitchensink.DoSignal_DoSignalActions_DoActions{ - DoActions: kitchensink.SingleActionSet(), - }, - } - if custom := signal.GetCustom(); custom != nil { - signalName = custom.GetName() - signalArg = custom.GetArgs() - } else if doActions := signal.GetDoSignalActions(); doActions != nil { - signalArg = doActions - } - - if signal.GetWithStart() { - startOptions := client.StartWorkflowOptions{ - ID: input.GetWorkflowId(), - TaskQueue: input.GetStartOptions().GetTaskQueue(), - WorkflowExecutionTimeout: 60 * time.Minute, - WorkflowIDConflictPolicy: enumspb.WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING, - } - if startOptions.TaskQueue == "" { - // Default to the task queue handling this Nexus request. - startOptions.TaskQueue = temporalnexus.GetOperationInfo(ctx).TaskQueue - } - workflowInput := cmp.Or(input.GetStartOptions().GetWorkflowInput(), &kitchensink.WorkflowInput{}) - run, err := temporalnexus.GetClient(ctx).SignalWithStartWorkflow( - ctx, input.GetWorkflowId(), signalName, signalArg, startOptions, - KitchenSinkWorkflow, workflowInput) - if err != nil { - return result, nexusOutboundError("SignalWithStartWorkflow", err) - } - return temporalnexus.NewSyncResult(kitchensink.ConvertToPayload(run.GetID())), nil - } - - err := temporalnexus.GetClient(ctx).SignalWorkflow( - ctx, input.GetWorkflowId(), input.GetRunId(), signalName, signalArg) - if err != nil { - return result, nexusOutboundError("SignalWorkflow", err) - } - return temporalnexus.NewSyncResult(kitchensink.ConvertToPayload(input.GetWorkflowId())), nil -} - -func updateWorkflowNexusOperation( - ctx context.Context, - nc temporalnexus.NexusClient, - input *kitchensink.NexusWorkflowAction, -) (temporalnexus.TemporalOperationResult[*common.Payload], error) { - var result temporalnexus.TemporalOperationResult[*common.Payload] - if input.GetWorkflowId() == "" { - return result, nexus.HandlerErrorf( - nexus.HandlerErrorTypeBadRequest, "update target must include a workflow ID") - } - if input.GetUpdate().GetWithStart() { - return result, nexus.HandlerErrorf( - nexus.HandlerErrorTypeBadRequest, "update-with-start is not supported by this Nexus operation") - } - - updateName := "do_actions_update" - var args []any - if custom := input.GetUpdate().GetCustom(); custom != nil { - updateName = custom.GetName() - args = []any{custom.GetArgs()} - } else { - update := cmp.Or(input.GetUpdate().GetDoActions(), &kitchensink.DoActionsUpdate{ - Variant: &kitchensink.DoActionsUpdate_DoActions{ - DoActions: kitchensink.SingleActionSet( - kitchensink.NewNexusUpdateResultAction(input.GetWorkflowId()), - ), - }, - }) - args = []any{update} - } - - // UpdateID is deliberately left unset: StartUpdateWorkflow derives it from the - // Nexus request ID, so a retried Nexus task attaches to the original update - // rather than starting a second one. - result, err := temporalnexus.StartUpdateWorkflow[*common.Payload](ctx, nc, client.UpdateWorkflowOptions{ - WorkflowID: input.GetWorkflowId(), - RunID: input.GetRunId(), - UpdateName: updateName, - Args: args, - // Accepted is the only stage a Nexus-backed update supports: the operation - // goes async once the update is accepted, and the update's result reaches - // the caller later through the operation's completion callback. - WaitForStage: client.WorkflowUpdateStageAccepted, - }) - if err != nil { - return result, nexusOutboundError("UpdateWorkflow", err) - } - return result, nil -} - // nexusOutboundError maps a failure from an RPC the handler issued to the right // Nexus handler error. Namespace handover is worth retrying; a disabled server // feature or a bad target is not, because no number of retries fixes either. From 27cd842f75761b557628d99e197963b1a657f297 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 7 Sep 2026 19:50:02 -0700 Subject: [PATCH 05/18] Simplify Nexus workflow action test setup --- loadgen/kitchen_sink_executor_test.go | 139 +++++++++--------- loadgen/kitchensink/helpers.go | 58 -------- .../go/workerlib/kitchensink/kitchen_sink.go | 11 +- 3 files changed, 76 insertions(+), 132 deletions(-) diff --git a/loadgen/kitchen_sink_executor_test.go b/loadgen/kitchen_sink_executor_test.go index 6e01603d..b3c7305e 100644 --- a/loadgen/kitchen_sink_executor_test.go +++ b/loadgen/kitchen_sink_executor_test.go @@ -9,7 +9,6 @@ import ( "testing" "time" - "github.com/google/uuid" "github.com/stretchr/testify/require" "github.com/temporalio/omes/clioptions" . "github.com/temporalio/omes/internal/workertest" @@ -18,7 +17,6 @@ import ( "go.temporal.io/api/common/v1" "go.temporal.io/api/enums/v1" "go.temporal.io/api/history/v1" - "go.temporal.io/api/workflowservice/v1" "go.temporal.io/sdk/client" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/durationpb" @@ -1219,8 +1217,9 @@ func TestKitchenSink(t *testing.T) { name: "NexusOperation/Sync/Signal", testInput: &TestInput{WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( &Action{Variant: &Action_NestedActionSet{NestedActionSet: &ActionSet{Actions: []*Action{ - NewNexusOperationAction("", - &NexusOperationRequest{ + &Action{Variant: &Action_NexusOperation{NexusOperation: &ExecuteNexusOperation{ + Operation: KitchenSinkNexusOperationName, + Input: &NexusOperationRequest{ Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ WorkflowId: "nexus-signal-target", StartOptions: &NexusWorkflowStartOptions{ @@ -1232,20 +1231,25 @@ func TestKitchenSink(t *testing.T) { Action: &NexusWorkflowAction_Start{Start: &emptypb.Empty{}}, }}, }, - nil, - &AwaitableChoice{Condition: &AwaitableChoice_WaitStarted{WaitStarted: &emptypb.Empty{}}}, - ), - NewNexusOperationAction("", - NexusSignalWorkflowRequest("nexus-signal-target", "", &DoSignal{ - Variant: &DoSignal_DoSignalActions_{DoSignalActions: &DoSignal_DoSignalActions{ - Variant: &DoSignal_DoSignalActions_DoActions{DoActions: SingleActionSet( - NewSetWorkflowStateAction("status", "done"), - )}, + AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitStarted{WaitStarted: &emptypb.Empty{}}}, + }}}, + &Action{Variant: &Action_NexusOperation{NexusOperation: &ExecuteNexusOperation{ + Operation: KitchenSinkNexusOperationName, + ExpectedOutput: ConvertToPayload("nexus-signal-target"), + AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitFinish{WaitFinish: &emptypb.Empty{}}}, + Input: &NexusOperationRequest{ + Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ + WorkflowId: "nexus-signal-target", + Action: &NexusWorkflowAction_Signal{Signal: &DoSignal{ + Variant: &DoSignal_DoSignalActions_{DoSignalActions: &DoSignal_DoSignalActions{ + Variant: &DoSignal_DoSignalActions_DoActions{DoActions: SingleActionSet( + NewSetWorkflowStateAction("status", "done"), + )}, + }}, + }}, }}, - }, nil), - ConvertToPayload("nexus-signal-target"), - WaitFinishChoice(), - ), + }, + }}}, &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}, }}}}, )}}, @@ -1257,18 +1261,28 @@ func TestKitchenSink(t *testing.T) { name: "NexusOperation/Sync/SignalWithStart", testInput: &TestInput{WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( &Action{Variant: &Action_NestedActionSet{NestedActionSet: &ActionSet{Actions: []*Action{ - NewNexusOperationAction("", - NexusSignalWorkflowRequest("nexus-sws-target", "", &DoSignal{ - Variant: &DoSignal_DoSignalActions_{DoSignalActions: &DoSignal_DoSignalActions{ - Variant: &DoSignal_DoSignalActions_DoActionsInMain{DoActionsInMain: SingleActionSet( + &Action{Variant: &Action_NexusOperation{NexusOperation: &ExecuteNexusOperation{ + Operation: KitchenSinkNexusOperationName, + ExpectedOutput: ConvertToPayload("nexus-sws-target"), + AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitFinish{WaitFinish: &emptypb.Empty{}}}, + Input: &NexusOperationRequest{ + Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ + WorkflowId: "nexus-sws-target", + StartOptions: &NexusWorkflowStartOptions{WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( + NewAwaitWorkflowStateAction("status", "done"), NewEmptyReturnResultAction(), - )}, + )}}, + Action: &NexusWorkflowAction_Signal{Signal: &DoSignal{ + Variant: &DoSignal_DoSignalActions_{DoSignalActions: &DoSignal_DoSignalActions{ + Variant: &DoSignal_DoSignalActions_DoActions{DoActions: SingleActionSet( + NewSetWorkflowStateAction("status", "done"), + )}, + }}, + WithStart: true, + }}, }}, - WithStart: true, - }, &NexusWorkflowStartOptions{WorkflowInput: &WorkflowInput{}}), - ConvertToPayload("nexus-sws-target"), - WaitFinishChoice(), - ), + }, + }}}, &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}, }}}}, )}}, @@ -1280,8 +1294,9 @@ func TestKitchenSink(t *testing.T) { name: "NexusOperation/Async/Update", testInput: &TestInput{WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( &Action{Variant: &Action_NestedActionSet{NestedActionSet: &ActionSet{Actions: []*Action{ - NewNexusOperationAction("", - &NexusOperationRequest{ + &Action{Variant: &Action_NexusOperation{NexusOperation: &ExecuteNexusOperation{ + Operation: KitchenSinkNexusOperationName, + Input: &NexusOperationRequest{ Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ WorkflowId: "nexus-update-target", StartOptions: &NexusWorkflowStartOptions{ @@ -1293,21 +1308,30 @@ func TestKitchenSink(t *testing.T) { Action: &NexusWorkflowAction_Start{Start: &emptypb.Empty{}}, }}, }, - nil, - &AwaitableChoice{Condition: &AwaitableChoice_WaitStarted{WaitStarted: &emptypb.Empty{}}}, - ), - NewNexusOperationAction("", - NexusUpdateWorkflowRequest("nexus-update-target", "", &DoUpdate{ - Variant: &DoUpdate_DoActions{DoActions: &DoActionsUpdate{ - Variant: &DoActionsUpdate_DoActions{DoActions: SingleActionSet( - NewSetWorkflowStateAction("status", "done"), - NewNexusUpdateResultAction("nexus-update-target"), - )}, + AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitStarted{WaitStarted: &emptypb.Empty{}}}, + }}}, + &Action{Variant: &Action_NexusOperation{NexusOperation: &ExecuteNexusOperation{ + Operation: KitchenSinkNexusOperationName, + ExpectedOutput: ConvertToPayload("nexus-update-target"), + AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitFinish{WaitFinish: &emptypb.Empty{}}}, + Input: &NexusOperationRequest{ + Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ + WorkflowId: "nexus-update-target", + Action: &NexusWorkflowAction_Update{Update: &DoUpdate{ + Variant: &DoUpdate_DoActions{DoActions: &DoActionsUpdate{ + Variant: &DoActionsUpdate_DoActions{DoActions: SingleActionSet( + NewSetWorkflowStateAction("status", "done"), + // The update handler's return value is itself encoded by the data converter + // before the server forwards it to the Nexus completion callback, so the value + // is wrapped twice here: the caller decodes the outer layer and compares the + // inner Payload against ExecuteNexusOperation.expected_output. + NewReturnResultAction(ConvertToPayload(ConvertToPayload("nexus-update-target"))), + )}, + }}, + }}, }}, - }), - ConvertToPayload("nexus-update-target"), - WaitFinishChoice(), - ), + }, + }}}, &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}, }}}}, )}}, @@ -1412,7 +1436,6 @@ func testForSDK( scenarioInfo := ScenarioInfo{ ScenarioName: "kitchenSinkTest", RunID: fmt.Sprintf("%s-%d", strings.ReplaceAll(t.Name(), "/", "-"), time.Now().Unix()), - ExecutionID: uuid.NewString(), Configuration: RunConfiguration{ Iterations: 1, }, @@ -1467,6 +1490,7 @@ func testForSDK( return nil }, UpdateWorkflowOptions: func(_ context.Context, _ *Run, opts *KitchenSinkWorkflowOptions) error { + opts.StartOptions.ID = scenarioInfo.RunID opts.StartOptions.WorkflowExecutionTimeout = workflowTimeout return nil }, @@ -1514,9 +1538,8 @@ func testSupportedFeature( } _, execErr := env.RunExecutorTest(t, testExecutor, scenarioInfo, sdk) - taskQueueName := TaskQueueForRun(scenarioInfo.RunID) historyEvents, historyErr := getWorkflowHistory( - t, env.TemporalClient(), env.Namespace(), taskQueueName, scenarioInfo.ExecutionID) + t, env.TemporalClient(), scenarioInfo.RunID) if execErr != nil { if len(historyEvents) > 0 { t.Logf("History events for debugging:") @@ -1561,29 +1584,9 @@ func (w *kitchenSinkTestWrapper) Run(ctx context.Context, info ScenarioInfo) err func getWorkflowHistory( t *testing.T, temporalClient client.Client, - namespace string, - taskQueueName string, - executionID string, + workflowID string, ) ([]*history.HistoryEvent, error) { - executions, err := temporalClient.ListWorkflow(t.Context(), - &workflowservice.ListWorkflowExecutionsRequest{ - Namespace: namespace, - Query: fmt.Sprintf( - "TaskQueue = '%s' AND WorkflowType = 'kitchenSink' AND %s = '%s'", - taskQueueName, OmesExecutionIDSearchAttribute, executionID), - }) - if err != nil { - return nil, fmt.Errorf("failed to list workflow executions: %w", err) - } - if len(executions.Executions) == 0 { - return nil, fmt.Errorf("no workflow executions found for task queue %s", taskQueueName) - } - if len(executions.Executions) > 1 { - t.Logf("Warning: found %d kitchenSink workflow executions for task queue %s, using the first one", len(executions.Executions), taskQueueName) - } - - execution := executions.Executions[0] - historyIter := temporalClient.GetWorkflowHistory(t.Context(), execution.Execution.WorkflowId, execution.Execution.RunId, false, enums.HISTORY_EVENT_FILTER_TYPE_ALL_EVENT) + historyIter := temporalClient.GetWorkflowHistory(t.Context(), workflowID, "", false, enums.HISTORY_EVENT_FILTER_TYPE_ALL_EVENT) var historyEvents []*history.HistoryEvent for historyIter.HasNext() { event, err := historyIter.Next() diff --git a/loadgen/kitchensink/helpers.go b/loadgen/kitchensink/helpers.go index d5efc721..e9d56d75 100644 --- a/loadgen/kitchensink/helpers.go +++ b/loadgen/kitchensink/helpers.go @@ -96,64 +96,6 @@ func ClientActions(clientActions ...*ClientAction) *ClientSequence { } } -func NexusSignalWorkflowRequest( - workflowID string, - runID string, - signal *DoSignal, - options *NexusWorkflowStartOptions, -) *NexusOperationRequest { - return &NexusOperationRequest{ - Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ - WorkflowId: workflowID, - RunId: runID, - StartOptions: options, - Action: &NexusWorkflowAction_Signal{Signal: signal}, - }}, - } -} - -func NexusUpdateWorkflowRequest(workflowID string, runID string, update *DoUpdate) *NexusOperationRequest { - return &NexusOperationRequest{ - Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ - WorkflowId: workflowID, - RunId: runID, - Action: &NexusWorkflowAction_Update{Update: update}, - }}, - } -} - -// NewNexusUpdateResultAction returns a Payload as the workflow update result. -// The update handler's return value is itself encoded by the data converter -// before the server forwards it to the Nexus completion callback, so the value -// is wrapped twice here: the caller decodes the outer layer and compares the -// inner Payload against ExecuteNexusOperation.expected_output. -func NewNexusUpdateResultAction(value any) *Action { - return NewReturnResultAction(ConvertToPayload(ConvertToPayload(value))) -} - -func NewNexusOperationAction( - endpoint string, - input *NexusOperationRequest, - expectedOutput *common.Payload, - awaitableChoice *AwaitableChoice, -) *Action { - return &Action{ - Variant: &Action_NexusOperation{NexusOperation: &ExecuteNexusOperation{ - Endpoint: endpoint, - Operation: KitchenSinkNexusOperationName, - ExpectedOutput: expectedOutput, - AwaitableChoice: awaitableChoice, - Input: input, - }}, - } -} - -// WaitFinishChoice awaits an operation through to completion. -func WaitFinishChoice() *AwaitableChoice { - return &AwaitableChoice{ - Condition: &AwaitableChoice_WaitFinish{WaitFinish: &emptypb.Empty{}}, - } -} func ClientActivity(clientSeq *ClientSequence, factory ActionFactory[ExecuteActivityAction]) *Action { activity := &ExecuteActivityAction{ ActivityType: &ExecuteActivityAction_Client{ diff --git a/workers/go/workerlib/kitchensink/kitchen_sink.go b/workers/go/workerlib/kitchensink/kitchen_sink.go index 79fb38d9..3173eb22 100644 --- a/workers/go/workerlib/kitchensink/kitchen_sink.go +++ b/workers/go/workerlib/kitchensink/kitchen_sink.go @@ -746,14 +746,13 @@ func startNexusOperation( // Nexus handler error. Namespace handover is worth retrying; a disabled server // feature or a bad target is not, because no number of retries fixes either. func nexusOutboundError(rpc string, err error) error { - var notActive *serviceerror.NamespaceNotActive - if errors.As(err, ¬Active) { + if _, ok := errors.AsType[*serviceerror.NamespaceNotActive](err); ok { return nexus.HandlerErrorf(nexus.HandlerErrorTypeUnavailable, "%s", err.Error()) } - var unimplemented *serviceerror.Unimplemented - var invalidArg *serviceerror.InvalidArgument - var notFound *serviceerror.NotFound - if errors.As(err, &unimplemented) || errors.As(err, &invalidArg) || errors.As(err, ¬Found) { + _, unimplemented := errors.AsType[*serviceerror.Unimplemented](err) + _, invalidArgument := errors.AsType[*serviceerror.InvalidArgument](err) + _, notFound := errors.AsType[*serviceerror.NotFound](err) + if unimplemented || invalidArgument || notFound { return nexus.HandlerErrorf(nexus.HandlerErrorTypeBadRequest, "%s failed: %s", rpc, err.Error()) } return fmt.Errorf("%s failed: %w", rpc, err) From e9eacf6ce4205d5fdb5cb55c7ec5d4a5fce7eacc Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Mon, 7 Sep 2026 21:17:35 -0700 Subject: [PATCH 06/18] Extract Nexus workflow test action wrappers --- loadgen/kitchen_sink_executor_test.go | 40 ++++++++++++++++----------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/loadgen/kitchen_sink_executor_test.go b/loadgen/kitchen_sink_executor_test.go index b3c7305e..3fd4e0f0 100644 --- a/loadgen/kitchen_sink_executor_test.go +++ b/loadgen/kitchen_sink_executor_test.go @@ -1216,8 +1216,8 @@ func TestKitchenSink(t *testing.T) { { name: "NexusOperation/Sync/Signal", testInput: &TestInput{WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( - &Action{Variant: &Action_NestedActionSet{NestedActionSet: &ActionSet{Actions: []*Action{ - &Action{Variant: &Action_NexusOperation{NexusOperation: &ExecuteNexusOperation{ + nestedActions( + nexusOperation(&ExecuteNexusOperation{ Operation: KitchenSinkNexusOperationName, Input: &NexusOperationRequest{ Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ @@ -1232,8 +1232,8 @@ func TestKitchenSink(t *testing.T) { }}, }, AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitStarted{WaitStarted: &emptypb.Empty{}}}, - }}}, - &Action{Variant: &Action_NexusOperation{NexusOperation: &ExecuteNexusOperation{ + }), + nexusOperation(&ExecuteNexusOperation{ Operation: KitchenSinkNexusOperationName, ExpectedOutput: ConvertToPayload("nexus-signal-target"), AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitFinish{WaitFinish: &emptypb.Empty{}}}, @@ -1249,9 +1249,9 @@ func TestKitchenSink(t *testing.T) { }}, }}, }, - }}}, + }), &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}, - }}}}, + ), )}}, historyMatcher: PartialHistoryMatcher(` NexusOperationCompleted {"links":[{"workflowEvent":{"workflowId":"nexus-signal-target","requestIdRef":{"eventType":"EVENT_TYPE_WORKFLOW_EXECUTION_SIGNALED"}}}]}`), @@ -1260,8 +1260,8 @@ func TestKitchenSink(t *testing.T) { { name: "NexusOperation/Sync/SignalWithStart", testInput: &TestInput{WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( - &Action{Variant: &Action_NestedActionSet{NestedActionSet: &ActionSet{Actions: []*Action{ - &Action{Variant: &Action_NexusOperation{NexusOperation: &ExecuteNexusOperation{ + nestedActions( + nexusOperation(&ExecuteNexusOperation{ Operation: KitchenSinkNexusOperationName, ExpectedOutput: ConvertToPayload("nexus-sws-target"), AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitFinish{WaitFinish: &emptypb.Empty{}}}, @@ -1282,9 +1282,9 @@ func TestKitchenSink(t *testing.T) { }}, }}, }, - }}}, + }), &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}, - }}}}, + ), )}}, historyMatcher: PartialHistoryMatcher(` NexusOperationCompleted {"links":[{"workflowEvent":{"workflowId":"nexus-sws-target","requestIdRef":{"eventType":"EVENT_TYPE_WORKFLOW_EXECUTION_SIGNALED"}}}]}`), @@ -1293,8 +1293,8 @@ func TestKitchenSink(t *testing.T) { { name: "NexusOperation/Async/Update", testInput: &TestInput{WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( - &Action{Variant: &Action_NestedActionSet{NestedActionSet: &ActionSet{Actions: []*Action{ - &Action{Variant: &Action_NexusOperation{NexusOperation: &ExecuteNexusOperation{ + nestedActions( + nexusOperation(&ExecuteNexusOperation{ Operation: KitchenSinkNexusOperationName, Input: &NexusOperationRequest{ Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ @@ -1309,8 +1309,8 @@ func TestKitchenSink(t *testing.T) { }}, }, AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitStarted{WaitStarted: &emptypb.Empty{}}}, - }}}, - &Action{Variant: &Action_NexusOperation{NexusOperation: &ExecuteNexusOperation{ + }), + nexusOperation(&ExecuteNexusOperation{ Operation: KitchenSinkNexusOperationName, ExpectedOutput: ConvertToPayload("nexus-update-target"), AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitFinish{WaitFinish: &emptypb.Empty{}}}, @@ -1331,9 +1331,9 @@ func TestKitchenSink(t *testing.T) { }}, }}, }, - }}}, + }), &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}, - }}}}, + ), )}}, historyMatcher: PartialHistoryMatcher(` NexusOperationCompleted {"links":[{"workflowEvent":{"workflowId":"nexus-update-target","requestIdRef":{"eventType":"EVENT_TYPE_WORKFLOW_EXECUTION_UPDATE_ACCEPTED"}}}]}`), @@ -1581,6 +1581,14 @@ func (w *kitchenSinkTestWrapper) Run(ctx context.Context, info ScenarioInfo) err return w.executor.Run(ctx, info) } +func nexusOperation(operation *ExecuteNexusOperation) *Action { + return &Action{Variant: &Action_NexusOperation{NexusOperation: operation}} +} + +func nestedActions(actions ...*Action) *Action { + return &Action{Variant: &Action_NestedActionSet{NestedActionSet: SingleActionSet(actions...)}} +} + func getWorkflowHistory( t *testing.T, temporalClient client.Client, From 18aad7f03ccc0fdc59536fdd3051ab20648f7501 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Tue, 8 Sep 2026 08:35:59 -0700 Subject: [PATCH 07/18] simplify --- loadgen/kitchen_sink_executor_test.go | 323 +++++++++++--------------- loadgen/kitchensink/helpers.go | 5 + scenarios/throughput_stress.go | 131 +++++------ 3 files changed, 199 insertions(+), 260 deletions(-) diff --git a/loadgen/kitchen_sink_executor_test.go b/loadgen/kitchen_sink_executor_test.go index 3fd4e0f0..2d4ebc56 100644 --- a/loadgen/kitchen_sink_executor_test.go +++ b/loadgen/kitchen_sink_executor_test.go @@ -950,21 +950,17 @@ func TestKitchenSink(t *testing.T) { testInput: &TestInput{ WorkflowInput: &WorkflowInput{ InitialActions: ListActionSet( - &Action{ - Variant: &Action_NexusOperation{ - NexusOperation: &ExecuteNexusOperation{ - Operation: KitchenSinkNexusOperationName, - Input: &NexusOperationRequest{ - Action: &NexusOperationRequest_Echo{Echo: "hello"}, - }, - AwaitableChoice: &AwaitableChoice{ - Condition: &AwaitableChoice_WaitFinish{ - WaitFinish: &emptypb.Empty{}, - }, - }, + NexusOperation(&ExecuteNexusOperation{ + Input: &NexusOperationRequest{ + Action: &NexusOperationRequest_Echo{Echo: "hello"}, + }, + AwaitableChoice: &AwaitableChoice{ + Condition: &AwaitableChoice_WaitFinish{ + WaitFinish: &emptypb.Empty{}, }, }, }), + ), }, }, historyMatcher: PartialHistoryMatcher(` @@ -977,22 +973,18 @@ func TestKitchenSink(t *testing.T) { testInput: &TestInput{ WorkflowInput: &WorkflowInput{ InitialActions: ListActionSet( - &Action{ - Variant: &Action_NexusOperation{ - NexusOperation: &ExecuteNexusOperation{ - Operation: KitchenSinkNexusOperationName, - Input: &NexusOperationRequest{ - Action: &NexusOperationRequest_Echo{Echo: "hello"}, - }, - ExpectedOutput: ConvertToPayload("goodbye"), - AwaitableChoice: &AwaitableChoice{ - Condition: &AwaitableChoice_WaitFinish{ - WaitFinish: &emptypb.Empty{}, - }, - }, + NexusOperation(&ExecuteNexusOperation{ + Input: &NexusOperationRequest{ + Action: &NexusOperationRequest_Echo{Echo: "hello"}, + }, + ExpectedOutput: ConvertToPayload("goodbye"), + AwaitableChoice: &AwaitableChoice{ + Condition: &AwaitableChoice_WaitFinish{ + WaitFinish: &emptypb.Empty{}, }, }, }), + ), }, }, historyMatcher: PartialHistoryMatcher(` @@ -1006,33 +998,29 @@ func TestKitchenSink(t *testing.T) { testInput: &TestInput{ WorkflowInput: &WorkflowInput{ InitialActions: ListActionSet( - &Action{ - Variant: &Action_NexusOperation{ - NexusOperation: &ExecuteNexusOperation{ - Operation: KitchenSinkNexusOperationName, - Input: &NexusOperationRequest{ - Action: &NexusOperationRequest_WorkflowAction{ - WorkflowAction: &NexusWorkflowAction{ - StartOptions: &NexusWorkflowStartOptions{ - WorkflowInput: &WorkflowInput{ - InitialActions: ListActionSet( - NewTimerAction(1), - NewEmptyReturnResultAction(), - ), - }, - }, - Action: &NexusWorkflowAction_Start{Start: &emptypb.Empty{}}, + NexusOperation(&ExecuteNexusOperation{ + Input: &NexusOperationRequest{ + Action: &NexusOperationRequest_WorkflowAction{ + WorkflowAction: &NexusWorkflowAction{ + StartOptions: &NexusWorkflowStartOptions{ + WorkflowInput: &WorkflowInput{ + InitialActions: ListActionSet( + NewTimerAction(1), + NewEmptyReturnResultAction(), + ), }, }, - }, - AwaitableChoice: &AwaitableChoice{ - Condition: &AwaitableChoice_WaitFinish{ - WaitFinish: &emptypb.Empty{}, - }, + Action: &NexusWorkflowAction_Start{Start: &emptypb.Empty{}}, }, }, }, + AwaitableChoice: &AwaitableChoice{ + Condition: &AwaitableChoice_WaitFinish{ + WaitFinish: &emptypb.Empty{}, + }, + }, }), + ), }, }, historyMatcher: PartialHistoryMatcher(` @@ -1046,32 +1034,28 @@ func TestKitchenSink(t *testing.T) { testInput: &TestInput{ WorkflowInput: &WorkflowInput{ InitialActions: ListActionSet( - &Action{ - Variant: &Action_NexusOperation{ - NexusOperation: &ExecuteNexusOperation{ - Operation: KitchenSinkNexusOperationName, - Input: &NexusOperationRequest{ - Action: &NexusOperationRequest_WorkflowAction{ - WorkflowAction: &NexusWorkflowAction{ - StartOptions: &NexusWorkflowStartOptions{ - WorkflowInput: &WorkflowInput{ - InitialActions: ListActionSet( - NewAwaitWorkflowStateAction("never", "resolves"), - ), - }, - }, - Action: &NexusWorkflowAction_Start{Start: &emptypb.Empty{}}, + NexusOperation(&ExecuteNexusOperation{ + Input: &NexusOperationRequest{ + Action: &NexusOperationRequest_WorkflowAction{ + WorkflowAction: &NexusWorkflowAction{ + StartOptions: &NexusWorkflowStartOptions{ + WorkflowInput: &WorkflowInput{ + InitialActions: ListActionSet( + NewAwaitWorkflowStateAction("never", "resolves"), + ), }, }, + Action: &NexusWorkflowAction_Start{Start: &emptypb.Empty{}}, }, - AwaitableChoice: &AwaitableChoice{ - Condition: &AwaitableChoice_CancelAfterStarted{ - CancelAfterStarted: &emptypb.Empty{}, - }, - }, + }, + }, + AwaitableChoice: &AwaitableChoice{ + Condition: &AwaitableChoice_CancelAfterStarted{ + CancelAfterStarted: &emptypb.Empty{}, }, }, }), + ), }, }, historyMatcher: PartialHistoryMatcher(` @@ -1086,21 +1070,17 @@ func TestKitchenSink(t *testing.T) { testInput: &TestInput{ WorkflowInput: &WorkflowInput{ InitialActions: ListActionSet( - &Action{ - Variant: &Action_NexusOperation{ - NexusOperation: &ExecuteNexusOperation{ - Operation: KitchenSinkNexusOperationName, - Input: &NexusOperationRequest{ - Action: &NexusOperationRequest_Echo{Echo: "abandoned"}, - }, - AwaitableChoice: &AwaitableChoice{ - Condition: &AwaitableChoice_Abandon{ - Abandon: &emptypb.Empty{}, - }, - }, + NexusOperation(&ExecuteNexusOperation{ + Input: &NexusOperationRequest{ + Action: &NexusOperationRequest_Echo{Echo: "abandoned"}, + }, + AwaitableChoice: &AwaitableChoice{ + Condition: &AwaitableChoice_Abandon{ + Abandon: &emptypb.Empty{}, }, }, }), + ), }, }, historyMatcher: PartialHistoryMatcher(` @@ -1211,47 +1191,41 @@ func TestKitchenSink(t *testing.T) { DoStandaloneActivityOperatorCommands_COMMAND_TYPE_RESET), standaloneActivityOperatorCommandsTestCase("Update", DoStandaloneActivityOperatorCommands_COMMAND_TYPE_UPDATE), - // These tests start one kitchenSink workflow, apply an action to it, then - // await pending actions. { name: "NexusOperation/Sync/Signal", testInput: &TestInput{WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( - nestedActions( - nexusOperation(&ExecuteNexusOperation{ - Operation: KitchenSinkNexusOperationName, - Input: &NexusOperationRequest{ - Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ - WorkflowId: "nexus-signal-target", - StartOptions: &NexusWorkflowStartOptions{ - WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( - NewAwaitWorkflowStateAction("status", "done"), - NewEmptyReturnResultAction(), + NexusOperation(&ExecuteNexusOperation{ + Input: &NexusOperationRequest{ + Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ + WorkflowId: "nexus-signal-target", + StartOptions: &NexusWorkflowStartOptions{ + WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( + NewAwaitWorkflowStateAction("status", "done"), + NewEmptyReturnResultAction(), + )}, + }, + Action: &NexusWorkflowAction_Start{Start: &emptypb.Empty{}}, + }}, + }, + AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitStarted{WaitStarted: &emptypb.Empty{}}}, + }), + NexusOperation(&ExecuteNexusOperation{ + ExpectedOutput: ConvertToPayload("nexus-signal-target"), + AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitFinish{WaitFinish: &emptypb.Empty{}}}, + Input: &NexusOperationRequest{ + Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ + WorkflowId: "nexus-signal-target", + Action: &NexusWorkflowAction_Signal{Signal: &DoSignal{ + Variant: &DoSignal_DoSignalActions_{DoSignalActions: &DoSignal_DoSignalActions{ + Variant: &DoSignal_DoSignalActions_DoActions{DoActions: SingleActionSet( + NewSetWorkflowStateAction("status", "done"), )}, - }, - Action: &NexusWorkflowAction_Start{Start: &emptypb.Empty{}}, - }}, - }, - AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitStarted{WaitStarted: &emptypb.Empty{}}}, - }), - nexusOperation(&ExecuteNexusOperation{ - Operation: KitchenSinkNexusOperationName, - ExpectedOutput: ConvertToPayload("nexus-signal-target"), - AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitFinish{WaitFinish: &emptypb.Empty{}}}, - Input: &NexusOperationRequest{ - Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ - WorkflowId: "nexus-signal-target", - Action: &NexusWorkflowAction_Signal{Signal: &DoSignal{ - Variant: &DoSignal_DoSignalActions_{DoSignalActions: &DoSignal_DoSignalActions{ - Variant: &DoSignal_DoSignalActions_DoActions{DoActions: SingleActionSet( - NewSetWorkflowStateAction("status", "done"), - )}, - }}, }}, }}, - }, - }), - &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}, - ), + }}, + }, + }), + &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}, )}}, historyMatcher: PartialHistoryMatcher(` NexusOperationCompleted {"links":[{"workflowEvent":{"workflowId":"nexus-signal-target","requestIdRef":{"eventType":"EVENT_TYPE_WORKFLOW_EXECUTION_SIGNALED"}}}]}`), @@ -1260,31 +1234,28 @@ func TestKitchenSink(t *testing.T) { { name: "NexusOperation/Sync/SignalWithStart", testInput: &TestInput{WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( - nestedActions( - nexusOperation(&ExecuteNexusOperation{ - Operation: KitchenSinkNexusOperationName, - ExpectedOutput: ConvertToPayload("nexus-sws-target"), - AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitFinish{WaitFinish: &emptypb.Empty{}}}, - Input: &NexusOperationRequest{ - Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ - WorkflowId: "nexus-sws-target", - StartOptions: &NexusWorkflowStartOptions{WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( - NewAwaitWorkflowStateAction("status", "done"), - NewEmptyReturnResultAction(), - )}}, - Action: &NexusWorkflowAction_Signal{Signal: &DoSignal{ - Variant: &DoSignal_DoSignalActions_{DoSignalActions: &DoSignal_DoSignalActions{ - Variant: &DoSignal_DoSignalActions_DoActions{DoActions: SingleActionSet( - NewSetWorkflowStateAction("status", "done"), - )}, - }}, - WithStart: true, + NexusOperation(&ExecuteNexusOperation{ + ExpectedOutput: ConvertToPayload("nexus-sws-target"), + AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitFinish{WaitFinish: &emptypb.Empty{}}}, + Input: &NexusOperationRequest{ + Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ + WorkflowId: "nexus-sws-target", + StartOptions: &NexusWorkflowStartOptions{WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( + NewAwaitWorkflowStateAction("status", "done"), + NewEmptyReturnResultAction(), + )}}, + Action: &NexusWorkflowAction_Signal{Signal: &DoSignal{ + Variant: &DoSignal_DoSignalActions_{DoSignalActions: &DoSignal_DoSignalActions{ + Variant: &DoSignal_DoSignalActions_DoActions{DoActions: SingleActionSet( + NewSetWorkflowStateAction("status", "done"), + )}, }}, + WithStart: true, }}, - }, - }), - &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}, - ), + }}, + }, + }), + &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}, )}}, historyMatcher: PartialHistoryMatcher(` NexusOperationCompleted {"links":[{"workflowEvent":{"workflowId":"nexus-sws-target","requestIdRef":{"eventType":"EVENT_TYPE_WORKFLOW_EXECUTION_SIGNALED"}}}]}`), @@ -1293,47 +1264,43 @@ func TestKitchenSink(t *testing.T) { { name: "NexusOperation/Async/Update", testInput: &TestInput{WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( - nestedActions( - nexusOperation(&ExecuteNexusOperation{ - Operation: KitchenSinkNexusOperationName, - Input: &NexusOperationRequest{ - Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ - WorkflowId: "nexus-update-target", - StartOptions: &NexusWorkflowStartOptions{ - WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( - NewAwaitWorkflowStateAction("status", "done"), - NewEmptyReturnResultAction(), + NexusOperation(&ExecuteNexusOperation{ + Input: &NexusOperationRequest{ + Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ + WorkflowId: "nexus-update-target", + StartOptions: &NexusWorkflowStartOptions{ + WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( + NewAwaitWorkflowStateAction("status", "done"), + NewEmptyReturnResultAction(), + )}, + }, + Action: &NexusWorkflowAction_Start{Start: &emptypb.Empty{}}, + }}, + }, + AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitStarted{WaitStarted: &emptypb.Empty{}}}, + }), + NexusOperation(&ExecuteNexusOperation{ + AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitFinish{WaitFinish: &emptypb.Empty{}}}, + Input: &NexusOperationRequest{ + Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ + WorkflowId: "nexus-update-target", + Action: &NexusWorkflowAction_Update{Update: &DoUpdate{ + Variant: &DoUpdate_DoActions{DoActions: &DoActionsUpdate{ + Variant: &DoActionsUpdate_DoActions{DoActions: SingleActionSet( + NewSetWorkflowStateAction("status", "done"), + // The update handler's return value is itself encoded by the data converter + // before the server forwards it to the Nexus completion callback, so the value + // is wrapped twice here: the caller decodes the outer layer and compares the + // inner Payload against ExecuteNexusOperation.expected_output. + NewReturnResultAction(ConvertToPayload(ConvertToPayload("nexus-update-target"))), )}, - }, - Action: &NexusWorkflowAction_Start{Start: &emptypb.Empty{}}, - }}, - }, - AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitStarted{WaitStarted: &emptypb.Empty{}}}, - }), - nexusOperation(&ExecuteNexusOperation{ - Operation: KitchenSinkNexusOperationName, - ExpectedOutput: ConvertToPayload("nexus-update-target"), - AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitFinish{WaitFinish: &emptypb.Empty{}}}, - Input: &NexusOperationRequest{ - Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ - WorkflowId: "nexus-update-target", - Action: &NexusWorkflowAction_Update{Update: &DoUpdate{ - Variant: &DoUpdate_DoActions{DoActions: &DoActionsUpdate{ - Variant: &DoActionsUpdate_DoActions{DoActions: SingleActionSet( - NewSetWorkflowStateAction("status", "done"), - // The update handler's return value is itself encoded by the data converter - // before the server forwards it to the Nexus completion callback, so the value - // is wrapped twice here: the caller decodes the outer layer and compares the - // inner Payload against ExecuteNexusOperation.expected_output. - NewReturnResultAction(ConvertToPayload(ConvertToPayload("nexus-update-target"))), - )}, - }}, }}, }}, - }, - }), - &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}, - ), + }}, + }, + ExpectedOutput: ConvertToPayload("nexus-update-target"), + }), + &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}, )}}, historyMatcher: PartialHistoryMatcher(` NexusOperationCompleted {"links":[{"workflowEvent":{"workflowId":"nexus-update-target","requestIdRef":{"eventType":"EVENT_TYPE_WORKFLOW_EXECUTION_UPDATE_ACCEPTED"}}}]}`), @@ -1581,14 +1548,6 @@ func (w *kitchenSinkTestWrapper) Run(ctx context.Context, info ScenarioInfo) err return w.executor.Run(ctx, info) } -func nexusOperation(operation *ExecuteNexusOperation) *Action { - return &Action{Variant: &Action_NexusOperation{NexusOperation: operation}} -} - -func nestedActions(actions ...*Action) *Action { - return &Action{Variant: &Action_NestedActionSet{NestedActionSet: SingleActionSet(actions...)}} -} - func getWorkflowHistory( t *testing.T, temporalClient client.Client, diff --git a/loadgen/kitchensink/helpers.go b/loadgen/kitchensink/helpers.go index e9d56d75..718c522b 100644 --- a/loadgen/kitchensink/helpers.go +++ b/loadgen/kitchensink/helpers.go @@ -86,6 +86,11 @@ func ListActionSet(actions ...*Action) []*ActionSet { } } +func NexusOperation(operation *ExecuteNexusOperation) *Action { + operation.Operation = KitchenSinkNexusOperationName + return &Action{Variant: &Action_NexusOperation{NexusOperation: operation}} +} + func ClientActions(clientActions ...*ClientAction) *ClientSequence { return &ClientSequence{ ActionSets: []*ClientActionSet{ diff --git a/scenarios/throughput_stress.go b/scenarios/throughput_stress.go index 6423f6cd..fbff4ffd 100644 --- a/scenarios/throughput_stress.go +++ b/scenarios/throughput_stress.go @@ -807,71 +807,56 @@ func (t *tpsExecutor) createSelfUpdateWithPayloadAsLocal() *ClientAction { } func (t *tpsExecutor) createNexusEchoSyncAction() *Action { - return &Action{ - Variant: &Action_NexusOperation{ - NexusOperation: &ExecuteNexusOperation{ - Endpoint: t.config.NexusEndpoint, - Operation: KitchenSinkNexusOperationName, - Input: &NexusOperationRequest{ - Action: &NexusOperationRequest_Echo{Echo: "hello"}, - }, - ExpectedOutput: ConvertToPayload("hello"), - }, + return NexusOperation(&ExecuteNexusOperation{ + Endpoint: t.config.NexusEndpoint, + Input: &NexusOperationRequest{ + Action: &NexusOperationRequest_Echo{Echo: "hello"}, }, - } + ExpectedOutput: ConvertToPayload("hello"), + }) } func (t *tpsExecutor) createNexusStartWorkflowAction() *Action { - return &Action{ - Variant: &Action_NexusOperation{ - NexusOperation: &ExecuteNexusOperation{ - Endpoint: t.config.NexusEndpoint, - Operation: KitchenSinkNexusOperationName, - Input: &NexusOperationRequest{ - Action: &NexusOperationRequest_WorkflowAction{ - WorkflowAction: &NexusWorkflowAction{ - StartOptions: &NexusWorkflowStartOptions{ - WorkflowInput: &WorkflowInput{ - InitialActions: ListActionSet(NewEmptyReturnResultAction()), - }, - }, - Action: &NexusWorkflowAction_Start{Start: &emptypb.Empty{}}, + return NexusOperation(&ExecuteNexusOperation{ + Endpoint: t.config.NexusEndpoint, + Input: &NexusOperationRequest{ + Action: &NexusOperationRequest_WorkflowAction{ + WorkflowAction: &NexusWorkflowAction{ + StartOptions: &NexusWorkflowStartOptions{ + WorkflowInput: &WorkflowInput{ + InitialActions: ListActionSet(NewEmptyReturnResultAction()), }, }, + Action: &NexusWorkflowAction_Start{Start: &emptypb.Empty{}}, }, }, }, - } + }) } func (t *tpsExecutor) createNexusWaitForCancelAction() *Action { - return &Action{ - Variant: &Action_NexusOperation{ - NexusOperation: &ExecuteNexusOperation{ - Endpoint: t.config.NexusEndpoint, - Operation: KitchenSinkNexusOperationName, - Input: &NexusOperationRequest{ - Action: &NexusOperationRequest_WorkflowAction{ - WorkflowAction: &NexusWorkflowAction{ - StartOptions: &NexusWorkflowStartOptions{ - WorkflowInput: &WorkflowInput{ - InitialActions: ListActionSet( - NewAwaitWorkflowStateAction("never", "resolves"), - ), - }, - }, - Action: &NexusWorkflowAction_Start{Start: &emptypb.Empty{}}, + return NexusOperation(&ExecuteNexusOperation{ + Endpoint: t.config.NexusEndpoint, + Input: &NexusOperationRequest{ + Action: &NexusOperationRequest_WorkflowAction{ + WorkflowAction: &NexusWorkflowAction{ + StartOptions: &NexusWorkflowStartOptions{ + WorkflowInput: &WorkflowInput{ + InitialActions: ListActionSet( + NewAwaitWorkflowStateAction("never", "resolves"), + ), }, }, - }, - AwaitableChoice: &AwaitableChoice{ - Condition: &AwaitableChoice_CancelAfterStarted{ - CancelAfterStarted: &emptypb.Empty{}, - }, + Action: &NexusWorkflowAction_Start{Start: &emptypb.Empty{}}, }, }, }, - } + AwaitableChoice: &AwaitableChoice{ + Condition: &AwaitableChoice_CancelAfterStarted{ + CancelAfterStarted: &emptypb.Empty{}, + }, + }, + }) } // createNexusAttachCallbacksAction exercises Nexus USE_EXISTING callback coalescing: @@ -881,28 +866,23 @@ func (t *tpsExecutor) createNexusAttachCallbacksAction() *Action { handlerWfID := "nexus-attach-handler-" + uuid.NewString() waitStartedOp := func() *Action { - return &Action{ - Variant: &Action_NexusOperation{ - NexusOperation: &ExecuteNexusOperation{ - Endpoint: t.config.NexusEndpoint, - Operation: KitchenSinkNexusOperationName, - Input: &NexusOperationRequest{ - Action: &NexusOperationRequest_WorkflowAction{ - WorkflowAction: &NexusWorkflowAction{ - WorkflowId: handlerWfID, - StartOptions: &NexusWorkflowStartOptions{ - WorkflowIdConflictPolicy: enumspb.WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING, - }, - Action: &NexusWorkflowAction_Start{Start: &emptypb.Empty{}}, - }, + return NexusOperation(&ExecuteNexusOperation{ + Endpoint: t.config.NexusEndpoint, + Input: &NexusOperationRequest{ + Action: &NexusOperationRequest_WorkflowAction{ + WorkflowAction: &NexusWorkflowAction{ + WorkflowId: handlerWfID, + StartOptions: &NexusWorkflowStartOptions{ + WorkflowIdConflictPolicy: enumspb.WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING, }, - }, - AwaitableChoice: &AwaitableChoice{ - Condition: &AwaitableChoice_WaitStarted{WaitStarted: &emptypb.Empty{}}, + Action: &NexusWorkflowAction_Start{Start: &emptypb.Empty{}}, }, }, }, - } + AwaitableChoice: &AwaitableChoice{ + Condition: &AwaitableChoice_WaitStarted{WaitStarted: &emptypb.Empty{}}, + }, + }) } fanout := make([]*Action, 0, numOps) for range numOps { @@ -942,19 +922,14 @@ func (t *tpsExecutor) createNexusAttachCallbacksAction() *Action { // createNexusStandaloneActivityAction invokes a standalone activity backed Nexus operation from within the workflow. func (t *tpsExecutor) createNexusStandaloneActivityAction() *Action { - return &Action{ - Variant: &Action_NexusOperation{ - NexusOperation: &ExecuteNexusOperation{ - Endpoint: t.config.NexusEndpoint, - Operation: KitchenSinkNexusOperationName, - Input: &NexusOperationRequest{ - Action: &NexusOperationRequest_StartActivity{StartActivity: &ExecuteActivityAction{ - ActivityType: &ExecuteActivityAction_Noop{}, - }}, - }, - }, + return NexusOperation(&ExecuteNexusOperation{ + Endpoint: t.config.NexusEndpoint, + Input: &NexusOperationRequest{ + Action: &NexusOperationRequest_StartActivity{StartActivity: &ExecuteActivityAction{ + ActivityType: &ExecuteActivityAction_Noop{}, + }}, }, - } + }) } func (t *tpsExecutor) createStandaloneNexusOperationAction(input *NexusOperationRequest) *Action { From 0d6ea06846cba5205f15a9df5bb4f7d3aec86e58 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Tue, 8 Sep 2026 08:47:09 -0700 Subject: [PATCH 08/18] Update kitchen_sink_executor_test.go --- loadgen/kitchen_sink_executor_test.go | 52 +++++++++++---------------- 1 file changed, 21 insertions(+), 31 deletions(-) diff --git a/loadgen/kitchen_sink_executor_test.go b/loadgen/kitchen_sink_executor_test.go index 2d4ebc56..6b837239 100644 --- a/loadgen/kitchen_sink_executor_test.go +++ b/loadgen/kitchen_sink_executor_test.go @@ -1210,8 +1210,6 @@ func TestKitchenSink(t *testing.T) { AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitStarted{WaitStarted: &emptypb.Empty{}}}, }), NexusOperation(&ExecuteNexusOperation{ - ExpectedOutput: ConvertToPayload("nexus-signal-target"), - AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitFinish{WaitFinish: &emptypb.Empty{}}}, Input: &NexusOperationRequest{ Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ WorkflowId: "nexus-signal-target", @@ -1224,6 +1222,7 @@ func TestKitchenSink(t *testing.T) { }}, }}, }, + ExpectedOutput: ConvertToPayload("nexus-signal-target"), }), &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}, )}}, @@ -1235,8 +1234,6 @@ func TestKitchenSink(t *testing.T) { name: "NexusOperation/Sync/SignalWithStart", testInput: &TestInput{WorkflowInput: &WorkflowInput{InitialActions: ListActionSet( NexusOperation(&ExecuteNexusOperation{ - ExpectedOutput: ConvertToPayload("nexus-sws-target"), - AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitFinish{WaitFinish: &emptypb.Empty{}}}, Input: &NexusOperationRequest{ Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ WorkflowId: "nexus-sws-target", @@ -1254,6 +1251,7 @@ func TestKitchenSink(t *testing.T) { }}, }}, }, + ExpectedOutput: ConvertToPayload("nexus-sws-target"), }), &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}, )}}, @@ -1280,7 +1278,6 @@ func TestKitchenSink(t *testing.T) { AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitStarted{WaitStarted: &emptypb.Empty{}}}, }), NexusOperation(&ExecuteNexusOperation{ - AwaitableChoice: &AwaitableChoice{Condition: &AwaitableChoice_WaitFinish{WaitFinish: &emptypb.Empty{}}}, Input: &NexusOperationRequest{ Action: &NexusOperationRequest_WorkflowAction{WorkflowAction: &NexusWorkflowAction{ WorkflowId: "nexus-update-target", @@ -1298,7 +1295,7 @@ func TestKitchenSink(t *testing.T) { }}, }}, }, - ExpectedOutput: ConvertToPayload("nexus-update-target"), + ExpectedOutput: ConvertToPayload("nexus-update-target"), }), &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}, )}}, @@ -1423,37 +1420,30 @@ func testForSDK( executor := &KitchenSinkExecutor{ TestInput: testInput, PrepareTestInput: func(_ context.Context, _ ScenarioInfo, input *TestInput) error { - var prepareActions func([]*Action) - prepareActions = func(actions []*Action) { - for _, action := range actions { - if nexusOp := action.GetNexusOperation(); nexusOp != nil && nexusOp.Endpoint == "" { - nexusOp.Endpoint = nexusEndpoint - } - if nested := action.GetNestedActionSet(); nested != nil { - prepareActions(nested.GetActions()) - } - if clientSeq := action.GetExecActivity().GetClient().GetClientSequence(); clientSeq != nil { - for _, cas := range clientSeq.ActionSets { - for _, ca := range cas.Actions { - if sno := ca.GetDoStandaloneNexusOperation().GetOperation(); sno != nil && sno.Endpoint == "" { - sno.Endpoint = nexusEndpoint - } - if sa := ca.GetDoStandaloneActivity(); sa.GetActivity() != nil && sa.GetActivity().TaskQueue == "" { - sa.GetActivity().TaskQueue = runTaskQueue - } - if op := ca.GetDoStandaloneActivityOperatorCommands(); op.GetActivity() != nil && op.GetActivity().TaskQueue == "" { - op.GetActivity().TaskQueue = runTaskQueue + if input.WorkflowInput != nil { + for _, actionSet := range input.WorkflowInput.InitialActions { + for _, action := range actionSet.Actions { + if nexusOp := action.GetNexusOperation(); nexusOp != nil && nexusOp.Endpoint == "" { + nexusOp.Endpoint = nexusEndpoint + } + if clientSeq := action.GetExecActivity().GetClient().GetClientSequence(); clientSeq != nil { + for _, cas := range clientSeq.ActionSets { + for _, ca := range cas.Actions { + if sno := ca.GetDoStandaloneNexusOperation().GetOperation(); sno != nil && sno.Endpoint == "" { + sno.Endpoint = nexusEndpoint + } + if sa := ca.GetDoStandaloneActivity(); sa.GetActivity() != nil && sa.GetActivity().TaskQueue == "" { + sa.GetActivity().TaskQueue = runTaskQueue + } + if op := ca.GetDoStandaloneActivityOperatorCommands(); op.GetActivity() != nil && op.GetActivity().TaskQueue == "" { + op.GetActivity().TaskQueue = runTaskQueue + } } } } } } } - if input.WorkflowInput != nil { - for _, actionSet := range input.WorkflowInput.InitialActions { - prepareActions(actionSet.Actions) - } - } return nil }, UpdateWorkflowOptions: func(_ context.Context, _ *Run, opts *KitchenSinkWorkflowOptions) error { From 04c6404fbec96742cc5434c2570cf9b56998b66b Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Tue, 8 Sep 2026 08:57:15 -0700 Subject: [PATCH 09/18] Update kitchen_sink_executor_test.go --- loadgen/kitchen_sink_executor_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/loadgen/kitchen_sink_executor_test.go b/loadgen/kitchen_sink_executor_test.go index 6b837239..6274714e 100644 --- a/loadgen/kitchen_sink_executor_test.go +++ b/loadgen/kitchen_sink_executor_test.go @@ -1495,8 +1495,7 @@ func testSupportedFeature( } _, execErr := env.RunExecutorTest(t, testExecutor, scenarioInfo, sdk) - historyEvents, historyErr := getWorkflowHistory( - t, env.TemporalClient(), scenarioInfo.RunID) + historyEvents, historyErr := getWorkflowHistory(t, env.TemporalClient(), scenarioInfo.RunID) if execErr != nil { if len(historyEvents) > 0 { t.Logf("History events for debugging:") From 4a0c84bc8d57bfd7f812497958195d51a22b12e0 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Tue, 8 Sep 2026 09:03:57 -0700 Subject: [PATCH 10/18] address review --- loadgen/kitchensink/client_action_executor.go | 43 ++++++----------- loadgen/kitchensink/helpers.go | 18 ++++++++ .../go/workerlib/kitchensink/kitchen_sink.go | 46 ++++++++----------- 3 files changed, 52 insertions(+), 55 deletions(-) diff --git a/loadgen/kitchensink/client_action_executor.go b/loadgen/kitchensink/client_action_executor.go index 33f83d03..68de9910 100644 --- a/loadgen/kitchensink/client_action_executor.go +++ b/loadgen/kitchensink/client_action_executor.go @@ -142,43 +142,28 @@ func (e *ClientActionsExecutor) executeClientAction(ctx context.Context, action } func (e *ClientActionsExecutor) executeSignalAction(ctx context.Context, sig *DoSignal) (client.WorkflowRun, error) { - var signalName string - var signalArgs any - if sigActions := sig.GetDoSignalActions(); sigActions != nil { - signalName = "do_actions_signal" - signalArgs = sigActions - } else if handler := sig.GetCustom(); handler != nil { - signalName = handler.Name - signalArgs = handler.Args - } else { - return nil, fmt.Errorf("do_signal must recognizable variant") + signalName, signalArg, err := SignalNameAndArg(sig) + if err != nil { + return nil, err } if sig.WithStart { return e.Client.SignalWithStartWorkflow( - ctx, e.WorkflowOptions.ID, signalName, signalArgs, e.WorkflowOptions, e.WorkflowType, e.WorkflowInput) + ctx, e.WorkflowOptions.ID, signalName, signalArg, e.WorkflowOptions, e.WorkflowType, e.WorkflowInput) } - return nil, e.Client.SignalWorkflow(ctx, e.WorkflowOptions.ID, "", signalName, signalArgs) + return nil, e.Client.SignalWorkflow(ctx, e.WorkflowOptions.ID, "", signalName, signalArg) } func (e *ClientActionsExecutor) executeUpdateAction(ctx context.Context, upd *DoUpdate) (run client.WorkflowRun, err error) { - var updateOpts client.UpdateWorkflowOptions - if actionsUpdate := upd.GetDoActions(); actionsUpdate != nil { - updateOpts = client.UpdateWorkflowOptions{ - WorkflowID: e.WorkflowOptions.ID, - UpdateName: "do_actions_update", - WaitForStage: client.WorkflowUpdateStageCompleted, - Args: []any{actionsUpdate}, - } - } else if handler := upd.GetCustom(); handler != nil { - updateOpts = client.UpdateWorkflowOptions{ - WorkflowID: e.WorkflowOptions.ID, - UpdateName: handler.Name, - WaitForStage: client.WorkflowUpdateStageCompleted, - Args: []any{handler.Args}, - } - } else { - return nil, fmt.Errorf("do_update must recognizable variant") + updateName, args, err := UpdateNameAndArgs(upd) + if err != nil { + return nil, err + } + updateOpts := client.UpdateWorkflowOptions{ + WorkflowID: e.WorkflowOptions.ID, + UpdateName: updateName, + WaitForStage: client.WorkflowUpdateStageCompleted, + Args: args, } var handle client.WorkflowUpdateHandle diff --git a/loadgen/kitchensink/helpers.go b/loadgen/kitchensink/helpers.go index 718c522b..04bbebc2 100644 --- a/loadgen/kitchensink/helpers.go +++ b/loadgen/kitchensink/helpers.go @@ -51,6 +51,24 @@ func ActivityNameAndArgs(act *ExecuteActivityAction) (string, []any) { return "noop", nil } +func SignalNameAndArg(signal *DoSignal) (string, any, error) { + if actions := signal.GetDoSignalActions(); actions != nil { + return "do_actions_signal", actions, nil + } else if handler := signal.GetCustom(); handler != nil { + return handler.GetName(), handler.GetArgs(), nil + } + return "", nil, fmt.Errorf("do_signal must recognizable variant") +} + +func UpdateNameAndArgs(update *DoUpdate) (string, []any, error) { + if actions := update.GetDoActions(); actions != nil { + return "do_actions_update", []any{actions}, nil + } else if handler := update.GetCustom(); handler != nil { + return handler.GetName(), []any{handler.GetArgs()}, nil + } + return "", nil, fmt.Errorf("do_update must recognizable variant") +} + // ConvertFromPBRetryPolicy converts a proto RetryPolicy into an SDK RetryPolicy. func ConvertFromPBRetryPolicy(retryPolicy *common.RetryPolicy) *temporal.RetryPolicy { if retryPolicy == nil { diff --git a/workers/go/workerlib/kitchensink/kitchen_sink.go b/workers/go/workerlib/kitchensink/kitchen_sink.go index 3173eb22..69d8fe96 100644 --- a/workers/go/workerlib/kitchensink/kitchen_sink.go +++ b/workers/go/workerlib/kitchensink/kitchen_sink.go @@ -650,19 +650,16 @@ func startNexusOperation( } signal := workflowAction.GetSignal() - signalName := "do_actions_signal" - // Default to an empty action set so an operation can exercise signal - // delivery without requiring the target workflow to run another action. - var signalArg any = &kitchensink.DoSignal_DoSignalActions{ - Variant: &kitchensink.DoSignal_DoSignalActions_DoActions{ - DoActions: kitchensink.SingleActionSet(), - }, - } - if custom := signal.GetCustom(); custom != nil { - signalName = custom.GetName() - signalArg = custom.GetArgs() - } else if doActions := signal.GetDoSignalActions(); doActions != nil { - signalArg = doActions + signalName, signalArg, err := kitchensink.SignalNameAndArg(signal) + if err != nil { + // Default to an empty action set so an operation can exercise signal + // delivery without requiring the target workflow to run another action. + signalName = "do_actions_signal" + signalArg = &kitchensink.DoSignal_DoSignalActions{ + Variant: &kitchensink.DoSignal_DoSignalActions_DoActions{ + DoActions: kitchensink.SingleActionSet(), + }, + } } if signal.GetWithStart() { @@ -687,7 +684,7 @@ func startNexusOperation( return temporalnexus.NewSyncResult(kitchensink.ConvertToPayload(run.GetID())), nil } - err := temporalnexus.GetClient(ctx).SignalWorkflow( + err = temporalnexus.GetClient(ctx).SignalWorkflow( ctx, workflowAction.GetWorkflowId(), workflowAction.GetRunId(), signalName, signalArg) if err != nil { return result, nexusOutboundError("SignalWorkflow", err) @@ -706,21 +703,15 @@ func startNexusOperation( "update-with-start is not supported by this Nexus operation") } - updateName := "do_actions_update" - var args []any - if custom := workflowAction.GetUpdate().GetCustom(); custom != nil { - updateName = custom.GetName() - args = []any{custom.GetArgs()} - } else if update := workflowAction.GetUpdate().GetDoActions(); update != nil { - args = []any{update} - } else { + updateName, args, err := kitchensink.UpdateNameAndArgs(workflowAction.GetUpdate()) + if err != nil { break } // UpdateID is deliberately left unset: StartUpdateWorkflow derives it from the // Nexus request ID, so a retried Nexus task attaches to the original update // rather than starting a second one. - result, err := temporalnexus.StartUpdateWorkflow[*common.Payload](ctx, nc, client.UpdateWorkflowOptions{ + result, err = temporalnexus.StartUpdateWorkflow[*common.Payload](ctx, nc, client.UpdateWorkflowOptions{ WorkflowID: workflowAction.GetWorkflowId(), RunID: workflowAction.GetRunId(), UpdateName: updateName, @@ -742,19 +733,22 @@ func startNexusOperation( nexus.HandlerErrorTypeBadRequest, "Nexus operation request has no supported action set") } -// nexusOutboundError maps a failure from an RPC the handler issued to the right -// Nexus handler error. Namespace handover is worth retrying; a disabled server -// feature or a bad target is not, because no number of retries fixes either. +// nexusOutboundError maps a failure from an RPC the handler issued to the right Nexus handler error. func nexusOutboundError(rpc string, err error) error { + // Namespace handover is worth retrying. if _, ok := errors.AsType[*serviceerror.NamespaceNotActive](err); ok { return nexus.HandlerErrorf(nexus.HandlerErrorTypeUnavailable, "%s", err.Error()) } + + // A disabled server feature or a bad target is not worth retrying, because no + // number of retries fixes either. _, unimplemented := errors.AsType[*serviceerror.Unimplemented](err) _, invalidArgument := errors.AsType[*serviceerror.InvalidArgument](err) _, notFound := errors.AsType[*serviceerror.NotFound](err) if unimplemented || invalidArgument || notFound { return nexus.HandlerErrorf(nexus.HandlerErrorTypeBadRequest, "%s failed: %s", rpc, err.Error()) } + return fmt.Errorf("%s failed: %w", rpc, err) } From db2b5cbd949eba01b83159f91c585e1838bf04f5 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Tue, 8 Sep 2026 09:08:29 -0700 Subject: [PATCH 11/18] Simplify Nexus workflow action handling --- loadgen/kitchensink/kitchen_sink.pb.go | 3 +- .../Temporalio.Omes/protos/KitchenSink.cs | 3 +- .../go/workerlib/kitchensink/kitchen_sink.go | 24 +++------- .../java/io/temporal/omes/KitchenSink.java | 45 +++++++------------ workers/proto/kitchen_sink/kitchen_sink.proto | 3 +- 5 files changed, 24 insertions(+), 54 deletions(-) diff --git a/loadgen/kitchensink/kitchen_sink.pb.go b/loadgen/kitchensink/kitchen_sink.pb.go index db52261e..ef351325 100644 --- a/loadgen/kitchensink/kitchen_sink.pb.go +++ b/loadgen/kitchensink/kitchen_sink.pb.go @@ -3517,8 +3517,7 @@ type NexusWorkflowAction_Start struct { type NexusWorkflowAction_Signal struct { // Signal the target workflow. Honors DoSignal.with_start, in which case // start_options supplies the workflow input and an existing workflow is reused. - // run_id selects the run for a signal without start. An unset DoSignal variant - // sends an empty do_actions_signal. + // run_id selects the run for a signal without start. Signal *DoSignal `protobuf:"bytes,5,opt,name=signal,proto3,oneof"` } diff --git a/workers/dotnet/Temporalio.Omes/protos/KitchenSink.cs b/workers/dotnet/Temporalio.Omes/protos/KitchenSink.cs index 72d17144..52827014 100644 --- a/workers/dotnet/Temporalio.Omes/protos/KitchenSink.cs +++ b/workers/dotnet/Temporalio.Omes/protos/KitchenSink.cs @@ -14825,8 +14825,7 @@ public string RunId { /// /// Signal the target workflow. Honors DoSignal.with_start, in which case /// start_options supplies the workflow input and an existing workflow is reused. - /// run_id selects the run for a signal without start. An unset DoSignal variant - /// sends an empty do_actions_signal. + /// run_id selects the run for a signal without start. /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] diff --git a/workers/go/workerlib/kitchensink/kitchen_sink.go b/workers/go/workerlib/kitchensink/kitchen_sink.go index 69d8fe96..80651d49 100644 --- a/workers/go/workerlib/kitchensink/kitchen_sink.go +++ b/workers/go/workerlib/kitchensink/kitchen_sink.go @@ -652,29 +652,18 @@ func startNexusOperation( signal := workflowAction.GetSignal() signalName, signalArg, err := kitchensink.SignalNameAndArg(signal) if err != nil { - // Default to an empty action set so an operation can exercise signal - // delivery without requiring the target workflow to run another action. - signalName = "do_actions_signal" - signalArg = &kitchensink.DoSignal_DoSignalActions{ - Variant: &kitchensink.DoSignal_DoSignalActions_DoActions{ - DoActions: kitchensink.SingleActionSet(), - }, - } + return result, nexus.HandlerErrorf(nexus.HandlerErrorTypeBadRequest, "%s", err.Error()) } if signal.GetWithStart() { + // Default to the task queue handling this Nexus request. startOptions := client.StartWorkflowOptions{ - ID: workflowAction.GetWorkflowId(), - TaskQueue: workflowAction.GetStartOptions().GetTaskQueue(), + ID: workflowAction.GetWorkflowId(), + TaskQueue: cmp.Or(workflowAction.GetStartOptions().GetTaskQueue(), temporalnexus.GetOperationInfo(ctx).TaskQueue), WorkflowExecutionTimeout: 60 * time.Minute, WorkflowIDConflictPolicy: enumspb.WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING, } - if startOptions.TaskQueue == "" { - // Default to the task queue handling this Nexus request. - startOptions.TaskQueue = temporalnexus.GetOperationInfo(ctx).TaskQueue - } - workflowInput := cmp.Or( - workflowAction.GetStartOptions().GetWorkflowInput(), &kitchensink.WorkflowInput{}) + workflowInput := cmp.Or(workflowAction.GetStartOptions().GetWorkflowInput(), &kitchensink.WorkflowInput{}) run, err := temporalnexus.GetClient(ctx).SignalWithStartWorkflow( ctx, workflowAction.GetWorkflowId(), signalName, signalArg, startOptions, KitchenSinkWorkflow, workflowInput) @@ -702,10 +691,9 @@ func startNexusOperation( nexus.HandlerErrorTypeBadRequest, "update-with-start is not supported by this Nexus operation") } - updateName, args, err := kitchensink.UpdateNameAndArgs(workflowAction.GetUpdate()) if err != nil { - break + return result, nexus.HandlerErrorf(nexus.HandlerErrorTypeBadRequest, "%s", err.Error()) } // UpdateID is deliberately left unset: StartUpdateWorkflow derives it from the diff --git a/workers/java/io/temporal/omes/KitchenSink.java b/workers/java/io/temporal/omes/KitchenSink.java index 44563e37..41d1d60c 100644 --- a/workers/java/io/temporal/omes/KitchenSink.java +++ b/workers/java/io/temporal/omes/KitchenSink.java @@ -56655,8 +56655,7 @@ public interface NexusWorkflowActionOrBuilder extends *
      * Signal the target workflow. Honors DoSignal.with_start, in which case
      * start_options supplies the workflow input and an existing workflow is reused.
-     * run_id selects the run for a signal without start. An unset DoSignal variant
-     * sends an empty do_actions_signal.
+     * run_id selects the run for a signal without start.
      * 
* * .temporal.omes.kitchen_sink.DoSignal signal = 5; @@ -56667,8 +56666,7 @@ public interface NexusWorkflowActionOrBuilder extends *
      * Signal the target workflow. Honors DoSignal.with_start, in which case
      * start_options supplies the workflow input and an existing workflow is reused.
-     * run_id selects the run for a signal without start. An unset DoSignal variant
-     * sends an empty do_actions_signal.
+     * run_id selects the run for a signal without start.
      * 
* * .temporal.omes.kitchen_sink.DoSignal signal = 5; @@ -56679,8 +56677,7 @@ public interface NexusWorkflowActionOrBuilder extends *
      * Signal the target workflow. Honors DoSignal.with_start, in which case
      * start_options supplies the workflow input and an existing workflow is reused.
-     * run_id selects the run for a signal without start. An unset DoSignal variant
-     * sends an empty do_actions_signal.
+     * run_id selects the run for a signal without start.
      * 
* * .temporal.omes.kitchen_sink.DoSignal signal = 5; @@ -56953,8 +56950,7 @@ public com.google.protobuf.EmptyOrBuilder getStartOrBuilder() { *
      * Signal the target workflow. Honors DoSignal.with_start, in which case
      * start_options supplies the workflow input and an existing workflow is reused.
-     * run_id selects the run for a signal without start. An unset DoSignal variant
-     * sends an empty do_actions_signal.
+     * run_id selects the run for a signal without start.
      * 
* * .temporal.omes.kitchen_sink.DoSignal signal = 5; @@ -56968,8 +56964,7 @@ public boolean hasSignal() { *
      * Signal the target workflow. Honors DoSignal.with_start, in which case
      * start_options supplies the workflow input and an existing workflow is reused.
-     * run_id selects the run for a signal without start. An unset DoSignal variant
-     * sends an empty do_actions_signal.
+     * run_id selects the run for a signal without start.
      * 
* * .temporal.omes.kitchen_sink.DoSignal signal = 5; @@ -56986,8 +56981,7 @@ public io.temporal.omes.KitchenSink.DoSignal getSignal() { *
      * Signal the target workflow. Honors DoSignal.with_start, in which case
      * start_options supplies the workflow input and an existing workflow is reused.
-     * run_id selects the run for a signal without start. An unset DoSignal variant
-     * sends an empty do_actions_signal.
+     * run_id selects the run for a signal without start.
      * 
* * .temporal.omes.kitchen_sink.DoSignal signal = 5; @@ -58026,8 +58020,7 @@ public com.google.protobuf.EmptyOrBuilder getStartOrBuilder() { *
        * Signal the target workflow. Honors DoSignal.with_start, in which case
        * start_options supplies the workflow input and an existing workflow is reused.
-       * run_id selects the run for a signal without start. An unset DoSignal variant
-       * sends an empty do_actions_signal.
+       * run_id selects the run for a signal without start.
        * 
* * .temporal.omes.kitchen_sink.DoSignal signal = 5; @@ -58041,8 +58034,7 @@ public boolean hasSignal() { *
        * Signal the target workflow. Honors DoSignal.with_start, in which case
        * start_options supplies the workflow input and an existing workflow is reused.
-       * run_id selects the run for a signal without start. An unset DoSignal variant
-       * sends an empty do_actions_signal.
+       * run_id selects the run for a signal without start.
        * 
* * .temporal.omes.kitchen_sink.DoSignal signal = 5; @@ -58066,8 +58058,7 @@ public io.temporal.omes.KitchenSink.DoSignal getSignal() { *
        * Signal the target workflow. Honors DoSignal.with_start, in which case
        * start_options supplies the workflow input and an existing workflow is reused.
-       * run_id selects the run for a signal without start. An unset DoSignal variant
-       * sends an empty do_actions_signal.
+       * run_id selects the run for a signal without start.
        * 
* * .temporal.omes.kitchen_sink.DoSignal signal = 5; @@ -58089,8 +58080,7 @@ public Builder setSignal(io.temporal.omes.KitchenSink.DoSignal value) { *
        * Signal the target workflow. Honors DoSignal.with_start, in which case
        * start_options supplies the workflow input and an existing workflow is reused.
-       * run_id selects the run for a signal without start. An unset DoSignal variant
-       * sends an empty do_actions_signal.
+       * run_id selects the run for a signal without start.
        * 
* * .temporal.omes.kitchen_sink.DoSignal signal = 5; @@ -58110,8 +58100,7 @@ public Builder setSignal( *
        * Signal the target workflow. Honors DoSignal.with_start, in which case
        * start_options supplies the workflow input and an existing workflow is reused.
-       * run_id selects the run for a signal without start. An unset DoSignal variant
-       * sends an empty do_actions_signal.
+       * run_id selects the run for a signal without start.
        * 
* * .temporal.omes.kitchen_sink.DoSignal signal = 5; @@ -58140,8 +58129,7 @@ public Builder mergeSignal(io.temporal.omes.KitchenSink.DoSignal value) { *
        * Signal the target workflow. Honors DoSignal.with_start, in which case
        * start_options supplies the workflow input and an existing workflow is reused.
-       * run_id selects the run for a signal without start. An unset DoSignal variant
-       * sends an empty do_actions_signal.
+       * run_id selects the run for a signal without start.
        * 
* * .temporal.omes.kitchen_sink.DoSignal signal = 5; @@ -58166,8 +58154,7 @@ public Builder clearSignal() { *
        * Signal the target workflow. Honors DoSignal.with_start, in which case
        * start_options supplies the workflow input and an existing workflow is reused.
-       * run_id selects the run for a signal without start. An unset DoSignal variant
-       * sends an empty do_actions_signal.
+       * run_id selects the run for a signal without start.
        * 
* * .temporal.omes.kitchen_sink.DoSignal signal = 5; @@ -58179,8 +58166,7 @@ public io.temporal.omes.KitchenSink.DoSignal.Builder getSignalBuilder() { *
        * Signal the target workflow. Honors DoSignal.with_start, in which case
        * start_options supplies the workflow input and an existing workflow is reused.
-       * run_id selects the run for a signal without start. An unset DoSignal variant
-       * sends an empty do_actions_signal.
+       * run_id selects the run for a signal without start.
        * 
* * .temporal.omes.kitchen_sink.DoSignal signal = 5; @@ -58200,8 +58186,7 @@ public io.temporal.omes.KitchenSink.DoSignalOrBuilder getSignalOrBuilder() { *
        * Signal the target workflow. Honors DoSignal.with_start, in which case
        * start_options supplies the workflow input and an existing workflow is reused.
-       * run_id selects the run for a signal without start. An unset DoSignal variant
-       * sends an empty do_actions_signal.
+       * run_id selects the run for a signal without start.
        * 
* * .temporal.omes.kitchen_sink.DoSignal signal = 5; diff --git a/workers/proto/kitchen_sink/kitchen_sink.proto b/workers/proto/kitchen_sink/kitchen_sink.proto index b3b6aca2..9f00cb0d 100644 --- a/workers/proto/kitchen_sink/kitchen_sink.proto +++ b/workers/proto/kitchen_sink/kitchen_sink.proto @@ -560,8 +560,7 @@ message NexusWorkflowAction { google.protobuf.Empty start = 4; // Signal the target workflow. Honors DoSignal.with_start, in which case // start_options supplies the workflow input and an existing workflow is reused. - // run_id selects the run for a signal without start. An unset DoSignal variant - // sends an empty do_actions_signal. + // run_id selects the run for a signal without start. DoSignal signal = 5; // Update the target workflow selected by workflow_id and run_id. // DoUpdate.with_start is not supported. From b89fe45511d44c5b4cb6c479c9c87ad077386a63 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Tue, 8 Sep 2026 09:18:43 -0700 Subject: [PATCH 12/18] Use SDK Nexus error mapping --- .../go/workerlib/kitchensink/kitchen_sink.go | 33 +++---------------- 1 file changed, 5 insertions(+), 28 deletions(-) diff --git a/workers/go/workerlib/kitchensink/kitchen_sink.go b/workers/go/workerlib/kitchensink/kitchen_sink.go index 80651d49..3751f039 100644 --- a/workers/go/workerlib/kitchensink/kitchen_sink.go +++ b/workers/go/workerlib/kitchensink/kitchen_sink.go @@ -658,8 +658,8 @@ func startNexusOperation( if signal.GetWithStart() { // Default to the task queue handling this Nexus request. startOptions := client.StartWorkflowOptions{ - ID: workflowAction.GetWorkflowId(), - TaskQueue: cmp.Or(workflowAction.GetStartOptions().GetTaskQueue(), temporalnexus.GetOperationInfo(ctx).TaskQueue), + ID: workflowAction.GetWorkflowId(), + TaskQueue: cmp.Or(workflowAction.GetStartOptions().GetTaskQueue(), temporalnexus.GetOperationInfo(ctx).TaskQueue), WorkflowExecutionTimeout: 60 * time.Minute, WorkflowIDConflictPolicy: enumspb.WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING, } @@ -668,7 +668,7 @@ func startNexusOperation( ctx, workflowAction.GetWorkflowId(), signalName, signalArg, startOptions, KitchenSinkWorkflow, workflowInput) if err != nil { - return result, nexusOutboundError("SignalWithStartWorkflow", err) + return result, err } return temporalnexus.NewSyncResult(kitchensink.ConvertToPayload(run.GetID())), nil } @@ -676,7 +676,7 @@ func startNexusOperation( err = temporalnexus.GetClient(ctx).SignalWorkflow( ctx, workflowAction.GetWorkflowId(), workflowAction.GetRunId(), signalName, signalArg) if err != nil { - return result, nexusOutboundError("SignalWorkflow", err) + return result, err } return temporalnexus.NewSyncResult( kitchensink.ConvertToPayload(workflowAction.GetWorkflowId())), nil @@ -699,7 +699,7 @@ func startNexusOperation( // UpdateID is deliberately left unset: StartUpdateWorkflow derives it from the // Nexus request ID, so a retried Nexus task attaches to the original update // rather than starting a second one. - result, err = temporalnexus.StartUpdateWorkflow[*common.Payload](ctx, nc, client.UpdateWorkflowOptions{ + return temporalnexus.StartUpdateWorkflow[*common.Payload](ctx, nc, client.UpdateWorkflowOptions{ WorkflowID: workflowAction.GetWorkflowId(), RunID: workflowAction.GetRunId(), UpdateName: updateName, @@ -709,10 +709,6 @@ func startNexusOperation( // the caller later through the operation's completion callback. WaitForStage: client.WorkflowUpdateStageAccepted, }) - if err != nil { - return result, nexusOutboundError("UpdateWorkflow", err) - } - return result, nil } case *kitchensink.NexusOperationRequest_StartActivity: return startStandaloneActivityNexusOperation(ctx, nc, action.StartActivity, opts) @@ -721,25 +717,6 @@ func startNexusOperation( nexus.HandlerErrorTypeBadRequest, "Nexus operation request has no supported action set") } -// nexusOutboundError maps a failure from an RPC the handler issued to the right Nexus handler error. -func nexusOutboundError(rpc string, err error) error { - // Namespace handover is worth retrying. - if _, ok := errors.AsType[*serviceerror.NamespaceNotActive](err); ok { - return nexus.HandlerErrorf(nexus.HandlerErrorTypeUnavailable, "%s", err.Error()) - } - - // A disabled server feature or a bad target is not worth retrying, because no - // number of retries fixes either. - _, unimplemented := errors.AsType[*serviceerror.Unimplemented](err) - _, invalidArgument := errors.AsType[*serviceerror.InvalidArgument](err) - _, notFound := errors.AsType[*serviceerror.NotFound](err) - if unimplemented || invalidArgument || notFound { - return nexus.HandlerErrorf(nexus.HandlerErrorTypeBadRequest, "%s failed: %s", rpc, err.Error()) - } - - return fmt.Errorf("%s failed: %w", rpc, err) -} - // startStandaloneActivityNexusOperation starts the registered "noop" activity. func startStandaloneActivityNexusOperation( ctx context.Context, From 12ed88c8b2c1504d70b6ff39f91950a5322b29b1 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Tue, 8 Sep 2026 09:44:34 -0700 Subject: [PATCH 13/18] Update kitchen_sink.go --- workers/go/workerlib/kitchensink/kitchen_sink.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/workers/go/workerlib/kitchensink/kitchen_sink.go b/workers/go/workerlib/kitchensink/kitchen_sink.go index 3751f039..797e6bb6 100644 --- a/workers/go/workerlib/kitchensink/kitchen_sink.go +++ b/workers/go/workerlib/kitchensink/kitchen_sink.go @@ -656,7 +656,6 @@ func startNexusOperation( } if signal.GetWithStart() { - // Default to the task queue handling this Nexus request. startOptions := client.StartWorkflowOptions{ ID: workflowAction.GetWorkflowId(), TaskQueue: cmp.Or(workflowAction.GetStartOptions().GetTaskQueue(), temporalnexus.GetOperationInfo(ctx).TaskQueue), @@ -688,8 +687,7 @@ func startNexusOperation( } if workflowAction.GetUpdate().GetWithStart() { return result, nexus.HandlerErrorf( - nexus.HandlerErrorTypeBadRequest, - "update-with-start is not supported by this Nexus operation") + nexus.HandlerErrorTypeBadRequest, "update-with-start is not supported by this Nexus operation") } updateName, args, err := kitchensink.UpdateNameAndArgs(workflowAction.GetUpdate()) if err != nil { From 37f963832bc3ff5bc7cd148c31752d647a1031a0 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Tue, 8 Sep 2026 09:47:40 -0700 Subject: [PATCH 14/18] Update kitchen_sink.go --- .../go/workerlib/kitchensink/kitchen_sink.go | 50 ++++++++++++------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/workers/go/workerlib/kitchensink/kitchen_sink.go b/workers/go/workerlib/kitchensink/kitchen_sink.go index 797e6bb6..b3eed6d6 100644 --- a/workers/go/workerlib/kitchensink/kitchen_sink.go +++ b/workers/go/workerlib/kitchensink/kitchen_sink.go @@ -627,6 +627,7 @@ func startNexusOperation( return temporalnexus.NewSyncResult(kitchensink.ConvertToPayload(action.Echo)), nil case *kitchensink.NexusOperationRequest_WorkflowAction: workflowAction := cmp.Or(action.WorkflowAction, &kitchensink.NexusWorkflowAction{}) + switch workflowAction.GetAction().(type) { case *kitchensink.NexusWorkflowAction_Start: startOptions := cmp.Or(workflowAction.GetStartOptions(), &kitchensink.NexusWorkflowStartOptions{}) @@ -640,8 +641,8 @@ func startNexusOperation( WorkflowIDConflictPolicy: startOptions.GetWorkflowIdConflictPolicy(), }, KitchenSinkWorkflow, - cmp.Or(startOptions.GetWorkflowInput(), &kitchensink.WorkflowInput{}), - ) + cmp.Or(startOptions.GetWorkflowInput(), &kitchensink.WorkflowInput{})) + case *kitchensink.NexusWorkflowAction_Signal: var result temporalnexus.TemporalOperationResult[*common.Payload] if workflowAction.GetWorkflowId() == "" { @@ -655,30 +656,39 @@ func startNexusOperation( return result, nexus.HandlerErrorf(nexus.HandlerErrorTypeBadRequest, "%s", err.Error()) } + // Signal-With-Start if signal.GetWithStart() { - startOptions := client.StartWorkflowOptions{ - ID: workflowAction.GetWorkflowId(), - TaskQueue: cmp.Or(workflowAction.GetStartOptions().GetTaskQueue(), temporalnexus.GetOperationInfo(ctx).TaskQueue), - WorkflowExecutionTimeout: 60 * time.Minute, - WorkflowIDConflictPolicy: enumspb.WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING, - } - workflowInput := cmp.Or(workflowAction.GetStartOptions().GetWorkflowInput(), &kitchensink.WorkflowInput{}) run, err := temporalnexus.GetClient(ctx).SignalWithStartWorkflow( - ctx, workflowAction.GetWorkflowId(), signalName, signalArg, startOptions, - KitchenSinkWorkflow, workflowInput) + ctx, + workflowAction.GetWorkflowId(), + signalName, + signalArg, + client.StartWorkflowOptions{ + ID: workflowAction.GetWorkflowId(), + TaskQueue: cmp.Or(workflowAction.GetStartOptions().GetTaskQueue(), temporalnexus.GetOperationInfo(ctx).TaskQueue), + WorkflowExecutionTimeout: 60 * time.Minute, + WorkflowIDConflictPolicy: enumspb.WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING, + }, + KitchenSinkWorkflow, + cmp.Or(workflowAction.GetStartOptions().GetWorkflowInput(), &kitchensink.WorkflowInput{})) if err != nil { return result, err } return temporalnexus.NewSyncResult(kitchensink.ConvertToPayload(run.GetID())), nil } - err = temporalnexus.GetClient(ctx).SignalWorkflow( - ctx, workflowAction.GetWorkflowId(), workflowAction.GetRunId(), signalName, signalArg) - if err != nil { + if err = temporalnexus.GetClient(ctx).SignalWorkflow( + ctx, + workflowAction.GetWorkflowId(), + workflowAction.GetRunId(), + signalName, + signalArg, + ); err != nil { return result, err } - return temporalnexus.NewSyncResult( - kitchensink.ConvertToPayload(workflowAction.GetWorkflowId())), nil + + return temporalnexus.NewSyncResult(kitchensink.ConvertToPayload(workflowAction.GetWorkflowId())), nil + case *kitchensink.NexusWorkflowAction_Update: var result temporalnexus.TemporalOperationResult[*common.Payload] if workflowAction.GetWorkflowId() == "" { @@ -689,6 +699,7 @@ func startNexusOperation( return result, nexus.HandlerErrorf( nexus.HandlerErrorTypeBadRequest, "update-with-start is not supported by this Nexus operation") } + updateName, args, err := kitchensink.UpdateNameAndArgs(workflowAction.GetUpdate()) if err != nil { return result, nexus.HandlerErrorf(nexus.HandlerErrorTypeBadRequest, "%s", err.Error()) @@ -708,11 +719,14 @@ func startNexusOperation( WaitForStage: client.WorkflowUpdateStageAccepted, }) } + case *kitchensink.NexusOperationRequest_StartActivity: return startStandaloneActivityNexusOperation(ctx, nc, action.StartActivity, opts) + + default: + return temporalnexus.TemporalOperationResult[*common.Payload]{}, nexus.HandlerErrorf( + nexus.HandlerErrorTypeBadRequest, "Nexus operation request has no supported action set") } - return temporalnexus.TemporalOperationResult[*common.Payload]{}, nexus.HandlerErrorf( - nexus.HandlerErrorTypeBadRequest, "Nexus operation request has no supported action set") } // startStandaloneActivityNexusOperation starts the registered "noop" activity. From 05498075ee248f787bb2ca6145ae0a754c60ef73 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Tue, 8 Sep 2026 09:54:47 -0700 Subject: [PATCH 15/18] Extract Nexus workflow action handlers --- .../go/workerlib/kitchensink/kitchen_sink.go | 194 ++++++++++-------- 1 file changed, 106 insertions(+), 88 deletions(-) diff --git a/workers/go/workerlib/kitchensink/kitchen_sink.go b/workers/go/workerlib/kitchensink/kitchen_sink.go index b3eed6d6..98646e9b 100644 --- a/workers/go/workerlib/kitchensink/kitchen_sink.go +++ b/workers/go/workerlib/kitchensink/kitchen_sink.go @@ -627,106 +627,124 @@ func startNexusOperation( return temporalnexus.NewSyncResult(kitchensink.ConvertToPayload(action.Echo)), nil case *kitchensink.NexusOperationRequest_WorkflowAction: workflowAction := cmp.Or(action.WorkflowAction, &kitchensink.NexusWorkflowAction{}) - switch workflowAction.GetAction().(type) { case *kitchensink.NexusWorkflowAction_Start: - startOptions := cmp.Or(workflowAction.GetStartOptions(), &kitchensink.NexusWorkflowStartOptions{}) - return temporalnexus.StartUntypedWorkflow[*common.Payload]( - ctx, - nc, - client.StartWorkflowOptions{ - ID: cmp.Or(workflowAction.GetWorkflowId(), opts.RequestID), - TaskQueue: startOptions.GetTaskQueue(), - WorkflowExecutionTimeout: 60 * time.Minute, - WorkflowIDConflictPolicy: startOptions.GetWorkflowIdConflictPolicy(), - }, - KitchenSinkWorkflow, - cmp.Or(startOptions.GetWorkflowInput(), &kitchensink.WorkflowInput{})) - + return startWorkflowNexusOperation(ctx, nc, workflowAction, opts) case *kitchensink.NexusWorkflowAction_Signal: - var result temporalnexus.TemporalOperationResult[*common.Payload] - if workflowAction.GetWorkflowId() == "" { - return result, nexus.HandlerErrorf( - nexus.HandlerErrorTypeBadRequest, "signal target must include a workflow ID") - } - - signal := workflowAction.GetSignal() - signalName, signalArg, err := kitchensink.SignalNameAndArg(signal) - if err != nil { - return result, nexus.HandlerErrorf(nexus.HandlerErrorTypeBadRequest, "%s", err.Error()) - } + return signalWorkflowNexusOperation(ctx, workflowAction) + case *kitchensink.NexusWorkflowAction_Update: + return updateWorkflowNexusOperation(ctx, nc, workflowAction) + } + case *kitchensink.NexusOperationRequest_StartActivity: + return startStandaloneActivityNexusOperation(ctx, nc, action.StartActivity, opts) + } + return temporalnexus.TemporalOperationResult[*common.Payload]{}, nexus.HandlerErrorf( + nexus.HandlerErrorTypeBadRequest, "Nexus operation request has no supported action set") +} - // Signal-With-Start - if signal.GetWithStart() { - run, err := temporalnexus.GetClient(ctx).SignalWithStartWorkflow( - ctx, - workflowAction.GetWorkflowId(), - signalName, - signalArg, - client.StartWorkflowOptions{ - ID: workflowAction.GetWorkflowId(), - TaskQueue: cmp.Or(workflowAction.GetStartOptions().GetTaskQueue(), temporalnexus.GetOperationInfo(ctx).TaskQueue), - WorkflowExecutionTimeout: 60 * time.Minute, - WorkflowIDConflictPolicy: enumspb.WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING, - }, - KitchenSinkWorkflow, - cmp.Or(workflowAction.GetStartOptions().GetWorkflowInput(), &kitchensink.WorkflowInput{})) - if err != nil { - return result, err - } - return temporalnexus.NewSyncResult(kitchensink.ConvertToPayload(run.GetID())), nil - } +func startWorkflowNexusOperation( + ctx context.Context, + nc temporalnexus.NexusClient, + input *kitchensink.NexusWorkflowAction, + opts temporalnexus.StartTemporalOperationOptions, +) (temporalnexus.TemporalOperationResult[*common.Payload], error) { + startOptions := cmp.Or(input.GetStartOptions(), &kitchensink.NexusWorkflowStartOptions{}) + return temporalnexus.StartUntypedWorkflow[*common.Payload]( + ctx, + nc, + client.StartWorkflowOptions{ + ID: cmp.Or(input.GetWorkflowId(), opts.RequestID), + TaskQueue: startOptions.GetTaskQueue(), + WorkflowExecutionTimeout: 60 * time.Minute, + WorkflowIDConflictPolicy: startOptions.GetWorkflowIdConflictPolicy(), + }, + KitchenSinkWorkflow, + cmp.Or(startOptions.GetWorkflowInput(), &kitchensink.WorkflowInput{})) +} - if err = temporalnexus.GetClient(ctx).SignalWorkflow( - ctx, - workflowAction.GetWorkflowId(), - workflowAction.GetRunId(), - signalName, - signalArg, - ); err != nil { - return result, err - } +func signalWorkflowNexusOperation( + ctx context.Context, + input *kitchensink.NexusWorkflowAction, +) (temporalnexus.TemporalOperationResult[*common.Payload], error) { + var result temporalnexus.TemporalOperationResult[*common.Payload] + if input.GetWorkflowId() == "" { + return result, nexus.HandlerErrorf( + nexus.HandlerErrorTypeBadRequest, "signal target must include a workflow ID") + } - return temporalnexus.NewSyncResult(kitchensink.ConvertToPayload(workflowAction.GetWorkflowId())), nil + signal := input.GetSignal() + signalName, signalArg, err := kitchensink.SignalNameAndArg(signal) + if err != nil { + return result, nexus.HandlerErrorf(nexus.HandlerErrorTypeBadRequest, "%s", err.Error()) + } - case *kitchensink.NexusWorkflowAction_Update: - var result temporalnexus.TemporalOperationResult[*common.Payload] - if workflowAction.GetWorkflowId() == "" { - return result, nexus.HandlerErrorf( - nexus.HandlerErrorTypeBadRequest, "update target must include a workflow ID") - } - if workflowAction.GetUpdate().GetWithStart() { - return result, nexus.HandlerErrorf( - nexus.HandlerErrorTypeBadRequest, "update-with-start is not supported by this Nexus operation") - } + // Signal-With-Start + if signal.GetWithStart() { + run, err := temporalnexus.GetClient(ctx).SignalWithStartWorkflow( + ctx, + input.GetWorkflowId(), + signalName, + signalArg, + client.StartWorkflowOptions{ + ID: input.GetWorkflowId(), + TaskQueue: cmp.Or(input.GetStartOptions().GetTaskQueue(), temporalnexus.GetOperationInfo(ctx).TaskQueue), + WorkflowExecutionTimeout: 60 * time.Minute, + WorkflowIDConflictPolicy: enumspb.WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING, + }, + KitchenSinkWorkflow, + cmp.Or(input.GetStartOptions().GetWorkflowInput(), &kitchensink.WorkflowInput{})) + if err != nil { + return result, err + } + return temporalnexus.NewSyncResult(kitchensink.ConvertToPayload(run.GetID())), nil + } - updateName, args, err := kitchensink.UpdateNameAndArgs(workflowAction.GetUpdate()) - if err != nil { - return result, nexus.HandlerErrorf(nexus.HandlerErrorTypeBadRequest, "%s", err.Error()) - } + if err = temporalnexus.GetClient(ctx).SignalWorkflow( + ctx, + input.GetWorkflowId(), + input.GetRunId(), + signalName, + signalArg, + ); err != nil { + return result, err + } - // UpdateID is deliberately left unset: StartUpdateWorkflow derives it from the - // Nexus request ID, so a retried Nexus task attaches to the original update - // rather than starting a second one. - return temporalnexus.StartUpdateWorkflow[*common.Payload](ctx, nc, client.UpdateWorkflowOptions{ - WorkflowID: workflowAction.GetWorkflowId(), - RunID: workflowAction.GetRunId(), - UpdateName: updateName, - Args: args, - // Accepted is the only stage a Nexus-backed update supports: the operation - // goes async once the update is accepted, and the update's result reaches - // the caller later through the operation's completion callback. - WaitForStage: client.WorkflowUpdateStageAccepted, - }) - } + return temporalnexus.NewSyncResult(kitchensink.ConvertToPayload(input.GetWorkflowId())), nil +} - case *kitchensink.NexusOperationRequest_StartActivity: - return startStandaloneActivityNexusOperation(ctx, nc, action.StartActivity, opts) +func updateWorkflowNexusOperation( + ctx context.Context, + nc temporalnexus.NexusClient, + input *kitchensink.NexusWorkflowAction, +) (temporalnexus.TemporalOperationResult[*common.Payload], error) { + var result temporalnexus.TemporalOperationResult[*common.Payload] + if input.GetWorkflowId() == "" { + return result, nexus.HandlerErrorf( + nexus.HandlerErrorTypeBadRequest, "update target must include a workflow ID") + } + if input.GetUpdate().GetWithStart() { + return result, nexus.HandlerErrorf( + nexus.HandlerErrorTypeBadRequest, "update-with-start is not supported by this Nexus operation") + } - default: - return temporalnexus.TemporalOperationResult[*common.Payload]{}, nexus.HandlerErrorf( - nexus.HandlerErrorTypeBadRequest, "Nexus operation request has no supported action set") + updateName, args, err := kitchensink.UpdateNameAndArgs(input.GetUpdate()) + if err != nil { + return result, nexus.HandlerErrorf(nexus.HandlerErrorTypeBadRequest, "%s", err.Error()) } + + // UpdateID is deliberately left unset: StartUpdateWorkflow derives it from the + // Nexus request ID, so a retried Nexus task attaches to the original update + // rather than starting a second one. + return temporalnexus.StartUpdateWorkflow[*common.Payload](ctx, nc, client.UpdateWorkflowOptions{ + WorkflowID: input.GetWorkflowId(), + RunID: input.GetRunId(), + UpdateName: updateName, + Args: args, + // Accepted is the only stage a Nexus-backed update supports: the operation + // goes async once the update is accepted, and the update's result reaches + // the caller later through the operation's completion callback. + WaitForStage: client.WorkflowUpdateStageAccepted, + }) } // startStandaloneActivityNexusOperation starts the registered "noop" activity. From 526fb07836e9d09b7f90e7e99018d80104383229 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Tue, 8 Sep 2026 17:29:31 -0700 Subject: [PATCH 16/18] Update kitchen_sink.go --- workers/go/workerlib/kitchensink/kitchen_sink.go | 1 + 1 file changed, 1 insertion(+) diff --git a/workers/go/workerlib/kitchensink/kitchen_sink.go b/workers/go/workerlib/kitchensink/kitchen_sink.go index 98646e9b..04e20fa5 100644 --- a/workers/go/workerlib/kitchensink/kitchen_sink.go +++ b/workers/go/workerlib/kitchensink/kitchen_sink.go @@ -662,6 +662,7 @@ func startWorkflowNexusOperation( cmp.Or(startOptions.GetWorkflowInput(), &kitchensink.WorkflowInput{})) } +// signalWorkflowNexusOperation handles both signal and Signal-With-Start. func signalWorkflowNexusOperation( ctx context.Context, input *kitchensink.NexusWorkflowAction, From b9047526b29912b4ea0dbdd99cdca3146b12c9fe Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Tue, 8 Sep 2026 17:43:02 -0700 Subject: [PATCH 17/18] Update kitchen_sink.go --- workers/go/workerlib/kitchensink/kitchen_sink.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workers/go/workerlib/kitchensink/kitchen_sink.go b/workers/go/workerlib/kitchensink/kitchen_sink.go index 04e20fa5..b42f82e8 100644 --- a/workers/go/workerlib/kitchensink/kitchen_sink.go +++ b/workers/go/workerlib/kitchensink/kitchen_sink.go @@ -690,7 +690,7 @@ func signalWorkflowNexusOperation( ID: input.GetWorkflowId(), TaskQueue: cmp.Or(input.GetStartOptions().GetTaskQueue(), temporalnexus.GetOperationInfo(ctx).TaskQueue), WorkflowExecutionTimeout: 60 * time.Minute, - WorkflowIDConflictPolicy: enumspb.WORKFLOW_ID_CONFLICT_POLICY_USE_EXISTING, + WorkflowIDConflictPolicy: input.GetStartOptions().GetWorkflowIdConflictPolicy(), }, KitchenSinkWorkflow, cmp.Or(input.GetStartOptions().GetWorkflowInput(), &kitchensink.WorkflowInput{})) From f6d9f64262904e3a85df14341272fa383c597669 Mon Sep 17 00:00:00 2001 From: Stephan Behnke Date: Tue, 8 Sep 2026 18:49:22 -0700 Subject: [PATCH 18/18] Exercise Nexus update callbacks --- loadgen/kitchen_sink_executor_test.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/loadgen/kitchen_sink_executor_test.go b/loadgen/kitchen_sink_executor_test.go index 6274714e..39d40488 100644 --- a/loadgen/kitchen_sink_executor_test.go +++ b/loadgen/kitchen_sink_executor_test.go @@ -103,6 +103,8 @@ func TestKitchenSink(t *testing.T) { "history.enableCHASMCallbacks": true, // Nexus Signals rely on CHASM signal backlinks. "history.enableCHASMSignalBacklinks": true, + // Nexus Updates rely on CHASM update callbacks. + "history.enableUpdateCallbacks": true, // Enable StartActivityExecution for the standalone-activity subtest. "activity.enableStandalone": true, "history.enableStandaloneActivityOperatorCommands": true, @@ -1284,6 +1286,7 @@ func TestKitchenSink(t *testing.T) { Action: &NexusWorkflowAction_Update{Update: &DoUpdate{ Variant: &DoUpdate_DoActions{DoActions: &DoActionsUpdate{ Variant: &DoActionsUpdate_DoActions{DoActions: SingleActionSet( + NewTimerAction(time.Millisecond), NewSetWorkflowStateAction("status", "done"), // The update handler's return value is itself encoded by the data converter // before the server forwards it to the Nexus completion callback, so the value @@ -1295,12 +1298,13 @@ func TestKitchenSink(t *testing.T) { }}, }}, }, - ExpectedOutput: ConvertToPayload("nexus-update-target"), + ExpectedOutput: ConvertToPayload(ConvertToPayload("nexus-update-target")), }), &Action{Variant: &Action_AwaitPendingActions{AwaitPendingActions: &AwaitPendingActions{}}}, )}}, historyMatcher: PartialHistoryMatcher(` - NexusOperationCompleted {"links":[{"workflowEvent":{"workflowId":"nexus-update-target","requestIdRef":{"eventType":"EVENT_TYPE_WORKFLOW_EXECUTION_UPDATE_ACCEPTED"}}}]}`), + NexusOperationStarted {"links":[{"workflowEvent":{"workflowId":"nexus-update-target","requestIdRef":{"eventType":"EVENT_TYPE_WORKFLOW_EXECUTION_UPDATE_ACCEPTED"}}}]} + NexusOperationCompleted`), expectedUnsupportedErrs: nexusWorkflowActionUnsupportedSDKs, }, {