From 87f7ded7d5af1d1ffd3f79d71513015ba7cb06da Mon Sep 17 00:00:00 2001 From: stevo89519 Date: Fri, 17 Jan 2025 14:21:18 -0500 Subject: [PATCH 1/5] IWF-439: Add comments for integration test workflows --- integ/workflow/any_command_close/routers.go | 7 ++- .../any_command_combination/routers.go | 15 +++++- integ/workflow/any_timer_signal/routers.go | 10 +++- integ/workflow/basic/routers.go | 7 +-- integ/workflow/conditional_close/routers.go | 13 +++-- integ/workflow/deadend/routers.go | 4 ++ integ/workflow/headers/routers.go | 4 +- integ/workflow/interstate/routers.go | 12 ++++- integ/workflow/locking/routers.go | 16 ++++-- integ/workflow/parallel/routers.go | 20 +++++-- integ/workflow/persistence/routers.go | 23 ++++++++ .../persistence_loading_policy/routers.go | 9 ++-- integ/workflow/rpc/routers.go | 6 ++- integ/workflow/signal/routers.go | 7 ++- integ/workflow/skipstart/routers.go | 4 +- integ/workflow/timer/routers.go | 7 ++- .../wait_for_state_completion/routers.go | 6 ++- .../wait_until_search_attributes/routers.go | 6 ++- .../routers.go | 54 +++++-------------- .../routers.go | 1 + integ/workflow/wf_force_fail/routers.go | 3 +- integ/workflow/wf_state_api_fail/routers.go | 1 + .../wf_state_api_fail_and_proceed/routers.go | 2 + .../workflow/wf_state_api_timeout/routers.go | 2 + .../routers.go | 16 +++--- .../routers.go | 16 +++--- 26 files changed, 179 insertions(+), 92 deletions(-) diff --git a/integ/workflow/any_command_close/routers.go b/integ/workflow/any_command_close/routers.go index 4887850d..311ee7ef 100644 --- a/integ/workflow/any_command_close/routers.go +++ b/integ/workflow/any_command_close/routers.go @@ -41,6 +41,8 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_start"]++ + + // Starting the first state, return trigger signals if req.GetWorkflowStateId() == State1 { c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ @@ -59,6 +61,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { }) return } + // Starting the second state, return "all completed" if req.GetWorkflowStateId() == State2 { c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ @@ -82,6 +85,8 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_decide"]++ + + // Trigger signals and move to next state if req.GetWorkflowStateId() == State1 { signalResults := req.GetCommandResults() h.invokeData["signalCommandResultsLength"] = len(signalResults.SignalResults) @@ -106,7 +111,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }) return } else if req.GetWorkflowStateId() == State2 { - // go to complete + // Move to completion c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ diff --git a/integ/workflow/any_command_combination/routers.go b/integ/workflow/any_command_combination/routers.go index bf0af376..612077e4 100644 --- a/integ/workflow/any_command_combination/routers.go +++ b/integ/workflow/any_command_combination/routers.go @@ -88,7 +88,10 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_start"]++ + + // Starting the first state if req.GetWorkflowStateId() == State1 { + // If the state has already retried an invalid command, return trigger signals and completion metrics if h.hasS1RetriedForInvalidCommandId { startResp := iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ @@ -112,6 +115,8 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { c.JSON(http.StatusOK, startResp) } else { + // If the state has not already retried an invalid command, return invalid trigger signals, which will fail + // and cause a retry startResp := iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ SignalCommands: validSignalCommands, @@ -124,7 +129,10 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { } return } + + // Starting the second state if req.GetWorkflowStateId() == State2 { + // If the state has already retried an invalid command, return signals and completion metrics if h.hasS2RetriedForInvalidCommandId { startResp := iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ @@ -148,6 +156,8 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { c.JSON(http.StatusOK, startResp) } else { + // If the state has not already retried an invalid command, return invalid trigger signals, which will fail + // and cause a retry startResp := iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ SignalCommands: invalidSignalCommands, @@ -174,6 +184,8 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_decide"]++ + + // Trigger signals and move to next state if req.GetWorkflowStateId() == State1 { h.invokeData["s1_commandResults"] = req.GetCommandResults() @@ -188,9 +200,8 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }) return } else if req.GetWorkflowStateId() == State2 { + // Fire signals and move to completion h.invokeData["s2_commandResults"] = req.GetCommandResults() - - // go to complete c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ diff --git a/integ/workflow/any_timer_signal/routers.go b/integ/workflow/any_timer_signal/routers.go index e0be00aa..26a3bfde 100644 --- a/integ/workflow/any_timer_signal/routers.go +++ b/integ/workflow/any_timer_signal/routers.go @@ -41,9 +41,13 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_start"]++ + + // Starting the first state if req.GetWorkflowStateId() == State1 { var timerCommands []iwfidl.TimerCommand context := req.GetContext() + + // Fire timer after 1s on first start attempt if context.GetStateExecutionId() == State1+"-"+"1" { now := time.Now().Unix() timerCommands = []iwfidl.TimerCommand{ @@ -67,6 +71,8 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { }) return } + + // Starting the second state, return "all completed" if req.GetWorkflowStateId() == State2 { c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ @@ -95,12 +101,14 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { var movements []iwfidl.StateMovement context := req.GetContext() + // On first state attempt, trigger signals and stay on the first state if context.GetStateExecutionId() == State1+"-"+"1" { h.invokeData["signalChannelName1"] = signalResults.SignalResults[0].GetSignalChannelName() h.invokeData["signalCommandId1"] = signalResults.SignalResults[0].GetCommandId() h.invokeData["signalStatus1"] = signalResults.SignalResults[0].GetSignalRequestStatus() movements = []iwfidl.StateMovement{{StateId: State1}} } else { + // After the first state attempt, trigger signals and move to next state h.invokeData["signalChannelName2"] = signalResults.SignalResults[0].GetSignalChannelName() h.invokeData["signalCommandId2"] = signalResults.SignalResults[0].GetCommandId() h.invokeData["signalStatus2"] = signalResults.SignalResults[0].GetSignalRequestStatus() @@ -115,7 +123,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }) return } else if req.GetWorkflowStateId() == State2 { - // go to complete + // Move to completion c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ diff --git a/integ/workflow/basic/routers.go b/integ/workflow/basic/routers.go index 1309ac90..2fa46156 100644 --- a/integ/workflow/basic/routers.go +++ b/integ/workflow/basic/routers.go @@ -39,7 +39,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { } if req.GetWorkflowType() == WorkflowType { - // basic workflow go straight to decide methods without any commands + // Basic workflow go straight to decide methods without any commands if req.GetWorkflowStateId() == State1 || req.GetWorkflowStateId() == State2 { h.invokeHistory[req.GetWorkflowStateId()+"_start"]++ c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ @@ -68,8 +68,9 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_decide"]++ + if req.GetWorkflowStateId() == State1 { - // go to S2 + // Move to next state c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -98,7 +99,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }) return } else if req.GetWorkflowStateId() == State2 { - // go to complete + // Move to completion c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ diff --git a/integ/workflow/conditional_close/routers.go b/integ/workflow/conditional_close/routers.go index a5172298..2d693116 100644 --- a/integ/workflow/conditional_close/routers.go +++ b/integ/workflow/conditional_close/routers.go @@ -45,6 +45,7 @@ func (h *handler) ApiV1WorkflowWorkerRpc(c *gin.Context) { log.Println("received workflow worker rpc request, ", req) h.invokeHistory[req.RpcName]++ + // Return channel name c.JSON(http.StatusOK, iwfidl.WorkflowWorkerRpcResponse{ PublishToInterStateChannel: []iwfidl.InterStateChannelPublishing{ { @@ -65,8 +66,11 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_start"]++ + + // Starting the first state if req.GetWorkflowStateId() == State1 { + // Return channel name cmdReq := &iwfidl.CommandRequest{ InterStateChannelCommands: []iwfidl.InterStateChannelCommand{ { @@ -76,8 +80,9 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { CommandWaitingType: ptr.Any(iwfidl.ANY_COMPLETED), } input := req.GetStateInput() + + // Return signal instead if input.GetData() == "use-signal-channel" { - // use signal cmdReq = &iwfidl.CommandRequest{ SignalCommands: []iwfidl.SignalCommand{ { @@ -87,6 +92,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { CommandWaitingType: ptr.Any(iwfidl.ANY_COMPLETED), } } + c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: cmdReq, }) @@ -112,7 +118,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { var internalChanPub []iwfidl.InterStateChannelPublishing context := req.GetContext() if context.GetStateExecutionId() == "S1-1" { - // wait for 3 seconds so that the channel can have a new message + // Wait for 3 seconds so that the channel can have a new message time.Sleep(time.Second * 3) } else if context.GetStateExecutionId() == "S1-3" { // send internal channel message within the state execution @@ -130,8 +136,9 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { CloseInput: &TestInput, } input := req.GetStateInput() + + // Use signal instead if input.GetData() == "use-signal-channel" { - // use signal conditionalClose = &iwfidl.WorkflowConditionalClose{ ConditionalCloseType: iwfidl.FORCE_COMPLETE_ON_SIGNAL_CHANNEL_EMPTY.Ptr(), ChannelName: iwfidl.PtrString(TestChannelName), diff --git a/integ/workflow/deadend/routers.go b/integ/workflow/deadend/routers.go index 0035c1f5..ab9f91e4 100644 --- a/integ/workflow/deadend/routers.go +++ b/integ/workflow/deadend/routers.go @@ -46,6 +46,7 @@ func (h *handler) ApiV1WorkflowWorkerRpc(c *gin.Context) { } if req.RpcName == RPCTriggerState { + // Move to first state c.JSON(http.StatusOK, iwfidl.WorkflowWorkerRpcResponse{ StateDecision: &iwfidl.StateDecision{NextStates: []iwfidl.StateMovement{ { @@ -57,6 +58,7 @@ func (h *handler) ApiV1WorkflowWorkerRpc(c *gin.Context) { }}, }) } else if req.RpcName == RPCWriteData { + // Upsert data attributes c.JSON(http.StatusOK, iwfidl.WorkflowWorkerRpcResponse{ UpsertDataAttributes: []iwfidl.KeyValue{ { @@ -88,6 +90,8 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_decide"]++ + + // Move to the dead-end state if req.GetWorkflowStateId() == State1 { c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ diff --git a/integ/workflow/headers/routers.go b/integ/workflow/headers/routers.go index 935543a0..b291bca0 100644 --- a/integ/workflow/headers/routers.go +++ b/integ/workflow/headers/routers.go @@ -42,7 +42,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { log.Println("received state start request, ", req) if req.GetWorkflowType() == WorkflowType { - // basic workflow go straight to decide methods without any commands + // Basic workflow to go straight to the decide methods without any commands if req.GetWorkflowStateId() == State1 { h.invokeHistory[req.GetWorkflowStateId()+"_start"]++ c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ @@ -74,7 +74,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_decide"]++ if req.GetWorkflowStateId() == State1 { - // go to S1 + // Move to completion c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ diff --git a/integ/workflow/interstate/routers.go b/integ/workflow/interstate/routers.go index 3986a3c5..1caa48ea 100644 --- a/integ/workflow/interstate/routers.go +++ b/integ/workflow/interstate/routers.go @@ -55,6 +55,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_start"]++ + // Go straight to the decide methods without any commands if req.GetWorkflowStateId() == State1 { c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ @@ -63,6 +64,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { }) return } + // Will proceed once channel 1 has been published to if req.GetWorkflowStateId() == State21 { c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ @@ -77,6 +79,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { }) return } + // Will proceed once channel 2 has been published to if req.GetWorkflowStateId() == State31 { c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ @@ -92,6 +95,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { return } + // Wait 2 seconds then publish on the first channel if req.GetWorkflowStateId() == State22 { time.Sleep(time.Second * 2) c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ @@ -124,6 +128,10 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_decide"]++ if req.GetWorkflowStateId() == State1 { + // First state requires no pre-reqs + // Move to state 21 & 22: + // 21 - Will wait for channel 1 + // 22 - Will wait 3 seconds then publish to channel 1 c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -143,6 +151,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { results := req.GetCommandResults() h.invokeData[State21+"received"] = results.GetInterStateChannelResults()[0].GetValue() + // Move to state 31, which will wait for channel 2 c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -159,6 +168,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { results := req.GetCommandResults() h.invokeData[State31+"received"] = results.GetInterStateChannelResults()[0].GetValue() + // Move to completion c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -174,7 +184,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { if req.GetWorkflowStateId() == State22 { time.Sleep(time.Second * 2) c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ - // real new dead end + // Move to the dead-end state and publish on channel 2 (to unlock State 31) StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ { diff --git a/integ/workflow/locking/routers.go b/integ/workflow/locking/routers.go index 16703643..0bb13920 100644 --- a/integ/workflow/locking/routers.go +++ b/integ/workflow/locking/routers.go @@ -102,6 +102,8 @@ func (h *handler) ApiV1WorkflowWorkerRpc(c *gin.Context) { if input.GetEncoding() != TestValue.GetEncoding() { panic("input is incorrect") } + + // Publish to internal channel if input.GetData() == ShouldUnblockStateWaiting { c.JSON(http.StatusOK, iwfidl.WorkflowWorkerRpcResponse{ PublishToInterStateChannel: []iwfidl.InterStateChannelPublishing{ @@ -127,9 +129,9 @@ func (h *handler) ApiV1WorkflowWorkerRpc(c *gin.Context) { } h.rpcInvokes++ - // this RPC will increase both SA and DA time.Sleep(time.Millisecond) + // This RPC will increase both SA and DA saInt := int64(0) for _, sa := range req.GetSearchAttributes() { if sa.GetKey() == TestSearchAttributeIntKey { @@ -221,6 +223,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_start"]++ + // Go straight to the decide methods without any commands if req.GetWorkflowStateId() == State1 { c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ @@ -229,6 +232,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { }) return } + // Will proceed once the internal channel has been published to if req.GetWorkflowStateId() == StateWaiting { c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ @@ -244,7 +248,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { } if req.GetWorkflowStateId() == State2 { - // this state API is to increase SA + // This state API is to increase SA time.Sleep(time.Second) saInt := int64(0) for _, sa := range req.GetSearchAttributes() { @@ -269,6 +273,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { }, } + // Go straight to the decide methods after updating SA c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ DeciderTriggerType: iwfidl.ALL_COMMAND_COMPLETED.Ptr(), @@ -303,6 +308,8 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { stms = append(stms, state2Movement) } + // Move to State Waiting, and 10 instances of State 2 + // State Waiting will not complete until the internal channel has been published to c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: stms, @@ -310,6 +317,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }) return } + // Move to completion if req.GetWorkflowStateId() == StateWaiting { c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ @@ -323,7 +331,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { return } if req.GetWorkflowStateId() == State2 { - // this API is to increase DA + // This API is to increase DA time.Sleep(time.Second) daInt := 0 for _, da := range req.DataObjects { @@ -341,6 +349,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { } daInt++ context := req.GetContext() + c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ UpsertDataObjects: []iwfidl.KeyValue{ { @@ -359,6 +368,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }, }, + // Move to completion StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ { diff --git a/integ/workflow/parallel/routers.go b/integ/workflow/parallel/routers.go index 4261f831..c1220828 100644 --- a/integ/workflow/parallel/routers.go +++ b/integ/workflow/parallel/routers.go @@ -43,6 +43,8 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_start"]++ + + // Go straight to the decide methods without any commands c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ DeciderTriggerType: iwfidl.ALL_COMMAND_COMPLETED.Ptr(), @@ -67,9 +69,10 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { var nextStates []iwfidl.StateMovement switch req.GetWorkflowStateId() { case State1: - // cause graceful complete to wait + // Cause graceful complete to wait time.Sleep(time.Second * 1) + // Move to 3 states (which will all move to this decide method without commands) nextStates = []iwfidl.StateMovement{ { StateId: State11, @@ -82,9 +85,10 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }, } case State11: - // cause graceful complete to wait + // Cause graceful complete to wait time.Sleep(time.Second * 2) + // Move to 2 states (which will all move to this decide method without commands) nextStates = []iwfidl.StateMovement{ { StateId: State111, @@ -94,8 +98,10 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }, } case State12: - // cause graceful complete to wait + // Cause graceful complete to wait time.Sleep(time.Second * 2) + + // Move to 2 states (which will all move to this decide method without commands) nextStates = []iwfidl.StateMovement{ { StateId: State121, @@ -105,8 +111,10 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }, } case State13: - // cause graceful complete to wait + // Cause graceful complete to wait time.Sleep(time.Second * 1) + + // Move to completion after updating the state input nextStates = []iwfidl.StateMovement{ { StateId: service.GracefulCompletingWorkflowStateId, @@ -116,7 +124,8 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }, }, } - case State112, State121, State122, State111: + case State111, State112, State121, State122: + // Move to completion after updating the state input nextStates = []iwfidl.StateMovement{ { StateId: service.GracefulCompletingWorkflowStateId, @@ -127,6 +136,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }, } default: + // Fail workflow due to unknown or unexpected state nextStates = []iwfidl.StateMovement{ { StateId: service.ForceFailingWorkflowStateId, diff --git a/integ/workflow/persistence/routers.go b/integ/workflow/persistence/routers.go index d6134c3b..5587eca1 100644 --- a/integ/workflow/persistence/routers.go +++ b/integ/workflow/persistence/routers.go @@ -103,6 +103,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { }, } + // Go to the decide methods after updating DA, SA, & SL c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ DeciderTriggerType: iwfidl.ALL_COMMAND_COMPLETED.Ptr(), @@ -129,6 +130,8 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { } if req.GetWorkflowStateId() == State2 { sas := req.GetSearchAttributes() + + // Determine how many keywords and ints are found in the search attributes kwSaFounds := 0 intSaFounds := 0 for _, sa := range sas { @@ -144,6 +147,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { h.invokeData["S2_start_kwSaFounds"] = kwSaFounds h.invokeData["S2_start_intSaFounds"] = intSaFounds + // Determine if the attribute is found in the request queryAttFound := false queryAtts := req.GetDataObjects() for _, queryAtt := range queryAtts { @@ -157,6 +161,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { } h.invokeData["S2_start_queryAttFound"] = queryAttFound + // Go straight to the decide methods without any commands c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ DeciderTriggerType: iwfidl.ALL_COMMAND_COMPLETED.Ptr(), @@ -166,6 +171,8 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { } if req.GetWorkflowStateId() == State3 { sas := req.GetSearchAttributes() + + // Determine if the INT attribute is found in the request found := false for _, sa := range sas { if sa.GetKey() == TestSearchAttributeKeywordKey { @@ -194,6 +201,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { panic("missing query attribute requested by partial loading keys") } + // Go straight to the decide methods without any commands c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ DeciderTriggerType: iwfidl.ALL_COMMAND_COMPLETED.Ptr(), @@ -218,6 +226,8 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { h.invokeHistory[req.GetWorkflowStateId()+"_decide"]++ if req.GetWorkflowStateId() == State1 { sas := req.GetSearchAttributes() + + // Determine how many keywords and ints are found in the search attributes kwSaFounds := 0 intSaFounds := 0 for _, sa := range sas { @@ -236,6 +246,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { queryAttFound := 0 queryAtts := req.GetDataObjects() + // Determine how many query attributes are found for _, queryAtt := range queryAtts { value := queryAtt.GetValue() if queryAtt.GetKey() == TestDataObjectKey && value.GetData() == TestDataObjectVal1.GetData() && value.GetEncoding() == TestDataObjectVal1.GetEncoding() { @@ -247,6 +258,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { } h.invokeData["S1_decide_queryAttFound"] = queryAttFound + // Determine if local attribute is found localAttFound := false localAtt := req.GetStateLocals()[0] value := localAtt.GetValue() @@ -269,6 +281,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }, } + // Move to state 2 with set options after updating values c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -303,6 +316,8 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { return } else if req.GetWorkflowStateId() == State2 { sas := req.GetSearchAttributes() + + // Determine how many keywords and ints are found in the search attributes kwSaFounds := 0 intSaFounds := 0 for _, sa := range sas { @@ -320,6 +335,8 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { queryAttFound := false queryAtts := req.GetDataObjects() + + // Determine how many query attributes are found for _, queryAtt := range queryAtts { value := queryAtt.GetValue() if queryAtt.GetKey() == TestDataObjectKey && value.GetData() == TestDataObjectVal2.GetData() && value.GetEncoding() == TestDataObjectVal2.GetEncoding() { @@ -332,6 +349,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { h.invokeData["S2_decide_queryAttFound"] = queryAttFound + // Move to state 3 after with set options c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -359,6 +377,8 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { return } else if req.GetWorkflowStateId() == State3 { sas := req.GetSearchAttributes() + + // Determine if the INT attribute is found in the request found := false for _, sa := range sas { if sa.GetKey() == TestSearchAttributeKeywordKey { @@ -375,6 +395,8 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { queryAttFound := 0 queryAtts := req.GetDataObjects() + + // Determine how many query attributes are found for _, queryAtt := range queryAtts { if queryAtt.GetKey() == TestDataObjectKey { queryAttFound++ @@ -387,6 +409,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { panic("missing query attribute requested by partial loading keys") } + // Move to completion c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ diff --git a/integ/workflow/persistence_loading_policy/routers.go b/integ/workflow/persistence_loading_policy/routers.go index 8aa5702c..e632df56 100644 --- a/integ/workflow/persistence_loading_policy/routers.go +++ b/integ/workflow/persistence_loading_policy/routers.go @@ -45,14 +45,14 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { h.invokeHistory[req.GetWorkflowStateId()+"_start"]++ if req.GetWorkflowStateId() == State2 { - // dynamically get the loadingType from input + // Dynamically get the loadingType from input loadingTypeFromInput := req.GetStateInput() loadingType := iwfidl.PersistenceLoadingType(loadingTypeFromInput.GetData()) verifyLoadedAttributes(req.GetSearchAttributes(), req.GetDataObjects(), loadingType) } - // go straight to decide methods without any commands + // Go straight to the decide methods without any commands c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ DeciderTriggerType: iwfidl.ANY_COMMAND_COMPLETED.Ptr(), @@ -75,7 +75,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { h.invokeHistory[req.GetWorkflowStateId()+"_decide"]++ - // dynamically get the loadingType from input + // Dynamically get the loadingType from input loadingTypeFromInput := req.GetStateInput() loadingType := iwfidl.PersistenceLoadingType(loadingTypeFromInput.GetData()) @@ -86,7 +86,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { var upsertSearchAttributes []iwfidl.SearchAttribute var upsertDataObjects []iwfidl.KeyValue - // set search attributes and data attributes in State1 + // Set search attributes and data attributes in State1 if req.GetWorkflowStateId() == State1 { upsertSearchAttributes = []iwfidl.SearchAttribute{ { @@ -119,6 +119,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { } } + // Move to dead-end (state 1) or completion (state 2) var nextStateId string if req.GetWorkflowStateId() == State1 { nextStateId = service.DeadEndWorkflowStateId diff --git a/integ/workflow/rpc/routers.go b/integ/workflow/rpc/routers.go index 5aa31922..57bf8640 100644 --- a/integ/workflow/rpc/routers.go +++ b/integ/workflow/rpc/routers.go @@ -124,6 +124,7 @@ func (h *handler) ApiV1WorkflowWorkerRpc(c *gin.Context) { }, } + // Proceed with State 2 after setting the attributes c.JSON(http.StatusOK, iwfidl.WorkflowWorkerRpcResponse{ Output: &TestOutput, StateDecision: &iwfidl.StateDecision{NextStates: []iwfidl.StateMovement{ @@ -183,6 +184,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { }, } + // Proceed after attributes and data objects have been updated and channel has been published to c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ InterStateChannelCommands: []iwfidl.InterStateChannelCommand{ @@ -203,6 +205,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { return } if req.GetWorkflowStateId() == State2 { + // Go straight to the decide methods without any commands c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ DeciderTriggerType: iwfidl.ALL_COMMAND_COMPLETED.Ptr(), @@ -233,6 +236,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { } h.invokeData[TestInterStateChannelName] = res.Value + // Move to state 2 c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -244,7 +248,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }) return } else if req.GetWorkflowStateId() == State2 { - // go to complete + // Move to completion c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ diff --git a/integ/workflow/signal/routers.go b/integ/workflow/signal/routers.go index b978e442..4b35dbe5 100644 --- a/integ/workflow/signal/routers.go +++ b/integ/workflow/signal/routers.go @@ -94,6 +94,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_start"]++ if req.GetWorkflowStateId() == State1 { + // Proceed when 4 signals are received c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ SignalCommands: []iwfidl.SignalCommand{ @@ -118,6 +119,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { return } if req.GetWorkflowStateId() == State2 { + // Go straight to the decide methods without any commands c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ DeciderTriggerType: iwfidl.ALL_COMMAND_COMPLETED.Ptr(), @@ -142,6 +144,8 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { h.invokeHistory[req.GetWorkflowStateId()+"_decide"]++ if req.GetWorkflowStateId() == State1 { signalResults := req.GetCommandResults() + + // Publish 4 signals for i := 0; i < 4; i++ { signalId := signalResults.SignalResults[i].GetCommandId() signalValue := signalResults.SignalResults[i].GetSignalValue() @@ -150,6 +154,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { h.invokeData[fmt.Sprintf("signalValue%v", i)] = signalValue } + // Move to State 2 c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -162,7 +167,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }) return } else if req.GetWorkflowStateId() == State2 { - // go to complete + // Move to completion c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ diff --git a/integ/workflow/skipstart/routers.go b/integ/workflow/skipstart/routers.go index a502cd4b..8ce303d1 100644 --- a/integ/workflow/skipstart/routers.go +++ b/integ/workflow/skipstart/routers.go @@ -40,7 +40,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_decide"]++ if req.GetWorkflowStateId() == State1 { - // go to S2 + // Move to State 2 with the provided input & options c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -56,7 +56,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }) return } else if req.GetWorkflowStateId() == State2 { - // go to complete + // Move to completion with the provided input c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ diff --git a/integ/workflow/timer/routers.go b/integ/workflow/timer/routers.go index 62553c00..b1dba97f 100644 --- a/integ/workflow/timer/routers.go +++ b/integ/workflow/timer/routers.go @@ -49,6 +49,8 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { } now := int64(nowInt) h.invokeData["scheduled_at"] = now + + // Proceed after 3 timers complete c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ TimerCommands: []iwfidl.TimerCommand{ @@ -70,6 +72,8 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { }) return } + + // Go straight to the decide methods without any commands if req.GetWorkflowStateId() == State2 { c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ @@ -99,6 +103,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { timerResults := req.GetCommandResults() timerId := timerResults.GetTimerResults()[0].GetCommandId() h.invokeData["timer_id"] = timerId + // Move to State 2 c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -110,7 +115,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }) return } else if req.GetWorkflowStateId() == State2 { - // go to complete + // Move to completion c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ diff --git a/integ/workflow/wait_for_state_completion/routers.go b/integ/workflow/wait_for_state_completion/routers.go index 7b5a2b59..4e306404 100644 --- a/integ/workflow/wait_for_state_completion/routers.go +++ b/integ/workflow/wait_for_state_completion/routers.go @@ -49,6 +49,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { } now := int64(nowInt) h.invokeData["scheduled_at"] = now + // Proceed after 10s c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ TimerCommands: []iwfidl.TimerCommand{ @@ -62,6 +63,8 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { }) return } + + // Go straight to the decide methods without any commands if req.GetWorkflowStateId() == State2 { c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ @@ -91,6 +94,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { timerResults := req.GetCommandResults() timerId := timerResults.GetTimerResults()[0].GetCommandId() h.invokeData["timer_id"] = timerId + // Move to State 2 c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -103,7 +107,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }) return } else if req.GetWorkflowStateId() == State2 { - // go to complete + // Move to completion c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ diff --git a/integ/workflow/wait_until_search_attributes/routers.go b/integ/workflow/wait_until_search_attributes/routers.go index 78aa9a8f..f4ce6866 100644 --- a/integ/workflow/wait_until_search_attributes/routers.go +++ b/integ/workflow/wait_until_search_attributes/routers.go @@ -18,7 +18,7 @@ import ( * - Execute method will go to State2 * State2: * - Waits on nothing. Will execute momentarily - * - Skips wait unit + * - Skips wait until * - 10-second delay is added before executing state * - Execute method will gracefully complete workflow */ @@ -51,6 +51,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_start"]++ if req.GetWorkflowStateId() == State1 { + // Go straight to the decide methods without any commands c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ DeciderTriggerType: iwfidl.ALL_COMMAND_COMPLETED.Ptr(), @@ -59,6 +60,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { return } if req.GetWorkflowStateId() == State2 { + // Go straight to the decide methods without any commands c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ DeciderTriggerType: iwfidl.ALL_COMMAND_COMPLETED.Ptr(), @@ -82,6 +84,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_decide"]++ if req.GetWorkflowStateId() == State1 { + // Move to State 2, skipping wait until c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -97,6 +100,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { return } else if req.GetWorkflowStateId() == State2 { time.Sleep(time.Second * 10) + // Move to completion c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ diff --git a/integ/workflow/wait_until_search_attributes_optimization/routers.go b/integ/workflow/wait_until_search_attributes_optimization/routers.go index b7a2230b..67c32cc6 100644 --- a/integ/workflow/wait_until_search_attributes_optimization/routers.go +++ b/integ/workflow/wait_until_search_attributes_optimization/routers.go @@ -69,23 +69,9 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_start"]++ - if req.GetWorkflowStateId() == State1 { - c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ - CommandRequest: &iwfidl.CommandRequest{ - DeciderTriggerType: iwfidl.ALL_COMMAND_COMPLETED.Ptr(), - }, - }) - return - } - if req.GetWorkflowStateId() == State2 { - c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ - CommandRequest: &iwfidl.CommandRequest{ - DeciderTriggerType: iwfidl.ALL_COMMAND_COMPLETED.Ptr(), - }, - }) - return - } - if req.GetWorkflowStateId() == State3 { + if req.GetWorkflowStateId() == State1 || req.GetWorkflowStateId() == State2 || req.GetWorkflowStateId() == State3 || + req.GetWorkflowStateId() == State5 || req.GetWorkflowStateId() == State6 || req.GetWorkflowStateId() == State7 { + // Go straight to the decide methods without any commands c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ DeciderTriggerType: iwfidl.ALL_COMMAND_COMPLETED.Ptr(), @@ -94,6 +80,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { return } if req.GetWorkflowStateId() == State4 { + // Proceed after signal is received c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ DeciderTriggerType: iwfidl.ALL_COMMAND_COMPLETED.Ptr(), @@ -107,30 +94,6 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { }) return } - if req.GetWorkflowStateId() == State5 { - c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ - CommandRequest: &iwfidl.CommandRequest{ - DeciderTriggerType: iwfidl.ALL_COMMAND_COMPLETED.Ptr(), - }, - }) - return - } - if req.GetWorkflowStateId() == State6 { - c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ - CommandRequest: &iwfidl.CommandRequest{ - DeciderTriggerType: iwfidl.ALL_COMMAND_COMPLETED.Ptr(), - }, - }) - return - } - if req.GetWorkflowStateId() == State7 { - c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ - CommandRequest: &iwfidl.CommandRequest{ - DeciderTriggerType: iwfidl.ALL_COMMAND_COMPLETED.Ptr(), - }, - }) - return - } } c.JSON(http.StatusBadRequest, struct{}{}) @@ -149,6 +112,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { if req.GetWorkflowStateId() == State1 { context := req.GetContext() if context.GetStateExecutionId() == "S1-5" { + // Move to State 2 c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -162,6 +126,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }, }) } else { + // Repeat State 1 (5 times) time.Sleep(time.Second * 1) c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ @@ -177,6 +142,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { } else if req.GetWorkflowStateId() == State2 { context := req.GetContext() if context.GetStateExecutionId() == "S2-2" { + // Move to State 3 & 4 c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -190,6 +156,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }, }) } else { + // Repeat State 2 and Move to State 3 c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -209,6 +176,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { return } else if req.GetWorkflowStateId() == State3 { time.Sleep(time.Second * 8) + // Move to Completion c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -220,6 +188,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }) return } else if req.GetWorkflowStateId() == State4 { + // Move to State 5, skipping wait until c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -234,6 +203,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }) return } else if req.GetWorkflowStateId() == State5 { + // Move to State 6 and State 7 skipping wait until for 7 c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -252,6 +222,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { return } else if req.GetWorkflowStateId() == State6 { time.Sleep(time.Second * 4) + // Move to completion c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -263,6 +234,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }) return } else if req.GetWorkflowStateId() == State7 { + // Move to completion c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ diff --git a/integ/workflow/wf_execute_api_fail_and_proceed/routers.go b/integ/workflow/wf_execute_api_fail_and_proceed/routers.go index 1975d235..6026c2b0 100644 --- a/integ/workflow/wf_execute_api_fail_and_proceed/routers.go +++ b/integ/workflow/wf_execute_api_fail_and_proceed/routers.go @@ -57,6 +57,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { } if req.WorkflowStateId == StateRecover { if input.GetData() == InputData && input.GetEncoding() == InputDataEncoding { + // Move to completion c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ diff --git a/integ/workflow/wf_force_fail/routers.go b/integ/workflow/wf_force_fail/routers.go index cbf03cb4..8f54ade1 100644 --- a/integ/workflow/wf_force_fail/routers.go +++ b/integ/workflow/wf_force_fail/routers.go @@ -42,6 +42,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_start"]++ if req.GetWorkflowStateId() == State1 { + // Empty response c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{}) return } @@ -60,7 +61,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { if req.GetWorkflowType() == WorkflowType && req.GetWorkflowStateId() == State1 { h.invokeHistory[req.GetWorkflowStateId()+"_decide"]++ - // go to complete + // Force fail c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ diff --git a/integ/workflow/wf_state_api_fail/routers.go b/integ/workflow/wf_state_api_fail/routers.go index e27de8a3..2c06c4cc 100644 --- a/integ/workflow/wf_state_api_fail/routers.go +++ b/integ/workflow/wf_state_api_fail/routers.go @@ -36,6 +36,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_start"]++ if req.GetWorkflowStateId() == State1 { + // Bad Request response c.JSON(http.StatusBadRequest, iwfidl.WorkflowStateStartResponse{}) return } diff --git a/integ/workflow/wf_state_api_fail_and_proceed/routers.go b/integ/workflow/wf_state_api_fail_and_proceed/routers.go index 1ebdcf08..5313a45e 100644 --- a/integ/workflow/wf_state_api_fail_and_proceed/routers.go +++ b/integ/workflow/wf_state_api_fail_and_proceed/routers.go @@ -38,6 +38,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_start"]++ if req.GetWorkflowStateId() == State1 { + // Bad Request response c.JSON(http.StatusBadRequest, iwfidl.WorkflowStateStartResponse{}) return } @@ -61,6 +62,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_decide"]++ } + // Move to completion c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ diff --git a/integ/workflow/wf_state_api_timeout/routers.go b/integ/workflow/wf_state_api_timeout/routers.go index e194ffed..53ab1ec3 100644 --- a/integ/workflow/wf_state_api_timeout/routers.go +++ b/integ/workflow/wf_state_api_timeout/routers.go @@ -37,7 +37,9 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_start"]++ if req.GetWorkflowStateId() == State1 { + // Sleep for longer than the timeout time.Sleep(time.Second * 30) + // Bad Request response c.JSON(http.StatusBadRequest, iwfidl.WorkflowStateStartResponse{}) return } diff --git a/integ/workflow/wf_state_options_data_attributes_loading/routers.go b/integ/workflow/wf_state_options_data_attributes_loading/routers.go index dd0c0af4..d765ed0a 100644 --- a/integ/workflow/wf_state_options_data_attributes_loading/routers.go +++ b/integ/workflow/wf_state_options_data_attributes_loading/routers.go @@ -75,7 +75,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { loadingTypeFromInput := req.GetStateInput() loadingType := iwfidl.PersistenceLoadingType(loadingTypeFromInput.GetData()) - if req.GetWorkflowStateId() == State2 { + if req.GetWorkflowStateId() == State2 || req.GetWorkflowStateId() == State4 || req.GetWorkflowStateId() == State5 { verifyLoadedDataAttributes(req.GetWorkflowStateId(), currentMethod, req.GetDataObjects(), loadingType) } @@ -83,14 +83,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { verifyEmptyDataAttributes(req.GetDataObjects()) } - if req.GetWorkflowStateId() == State4 { - verifyLoadedDataAttributes(req.GetWorkflowStateId(), currentMethod, req.GetDataObjects(), loadingType) - } - - if req.GetWorkflowStateId() == State5 { - verifyLoadedDataAttributes(req.GetWorkflowStateId(), currentMethod, req.GetDataObjects(), loadingType) - } - + // Go straight to the decide methods without any commands c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ DeciderTriggerType: iwfidl.ANY_COMMAND_COMPLETED.Ptr(), @@ -148,6 +141,7 @@ func getState1DecideResponse(req iwfidl.WorkflowStateDecideRequest) iwfidl.Workf loadingType := iwfidl.PersistenceLoadingType(loadingTypeFromInput.GetData()) noneLoadingType := iwfidl.NONE + // Move to State 2 with provided options & input after updating data objects return iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -175,6 +169,7 @@ func getState2DecideResponse(req iwfidl.WorkflowStateDecideRequest) iwfidl.Workf loadingType := iwfidl.PersistenceLoadingType(loadingTypeFromInput.GetData()) noneLoadingType := iwfidl.NONE + // Move to State 3 with provided options & input return iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -200,6 +195,7 @@ func getState3DecideResponse(req iwfidl.WorkflowStateDecideRequest) iwfidl.Workf loadingTypeFromInput := req.GetStateInput() loadingType := iwfidl.PersistenceLoadingType(loadingTypeFromInput.GetData()) + // Move to State 4 with provided options & input return iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -222,6 +218,7 @@ func getState4DecideResponse(req iwfidl.WorkflowStateDecideRequest) iwfidl.Workf loadingTypeFromInput := req.GetStateInput() loadingType := iwfidl.PersistenceLoadingType(loadingTypeFromInput.GetData()) + // Move to State 5 with provided options & input return iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -245,6 +242,7 @@ func getState4DecideResponse(req iwfidl.WorkflowStateDecideRequest) iwfidl.Workf } func getState5DecideResponse() iwfidl.WorkflowStateDecideResponse { + // Move to completion return iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ diff --git a/integ/workflow/wf_state_options_search_attributes_loading/routers.go b/integ/workflow/wf_state_options_search_attributes_loading/routers.go index 6dd87fd6..8e4917e0 100644 --- a/integ/workflow/wf_state_options_search_attributes_loading/routers.go +++ b/integ/workflow/wf_state_options_search_attributes_loading/routers.go @@ -76,7 +76,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { loadingTypeFromInput := req.GetStateInput() loadingType := iwfidl.PersistenceLoadingType(loadingTypeFromInput.GetData()) - if req.GetWorkflowStateId() == State2 { + if req.GetWorkflowStateId() == State2 || req.GetWorkflowStateId() == State4 || req.GetWorkflowStateId() == State5 { verifyLoadedSearchAttributes(req.GetWorkflowStateId(), currentMethod, req.GetSearchAttributes(), loadingType) } @@ -84,14 +84,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { verifyEmptySearchAttributes(req.GetSearchAttributes()) } - if req.GetWorkflowStateId() == State4 { - verifyLoadedSearchAttributes(req.GetWorkflowStateId(), currentMethod, req.GetSearchAttributes(), loadingType) - } - - if req.GetWorkflowStateId() == State5 { - verifyLoadedSearchAttributes(req.GetWorkflowStateId(), currentMethod, req.GetSearchAttributes(), loadingType) - } - + // Go straight to the decide methods without any commands c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ DeciderTriggerType: iwfidl.ANY_COMMAND_COMPLETED.Ptr(), @@ -149,6 +142,7 @@ func getState1DecideResponse(req iwfidl.WorkflowStateDecideRequest) iwfidl.Workf loadingType := iwfidl.PersistenceLoadingType(loadingTypeFromInput.GetData()) noneLoadingType := iwfidl.NONE + // Move to State 2 with the provided options & input after updating data objects return iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -176,6 +170,7 @@ func getState2DecideResponse(req iwfidl.WorkflowStateDecideRequest) iwfidl.Workf loadingType := iwfidl.PersistenceLoadingType(loadingTypeFromInput.GetData()) noneLoadingType := iwfidl.NONE + // Move to State 3 with the provided options & input return iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -201,6 +196,7 @@ func getState3DecideResponse(req iwfidl.WorkflowStateDecideRequest) iwfidl.Workf loadingTypeFromInput := req.GetStateInput() loadingType := iwfidl.PersistenceLoadingType(loadingTypeFromInput.GetData()) + // Move to State 4 with the provided options & input return iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -223,6 +219,7 @@ func getState4DecideResponse(req iwfidl.WorkflowStateDecideRequest) iwfidl.Workf loadingTypeFromInput := req.GetStateInput() loadingType := iwfidl.PersistenceLoadingType(loadingTypeFromInput.GetData()) + // Move to State 5 with the provided options & input return iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ @@ -246,6 +243,7 @@ func getState4DecideResponse(req iwfidl.WorkflowStateDecideRequest) iwfidl.Workf } func getState5DecideResponse() iwfidl.WorkflowStateDecideResponse { + // Move to completion return iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ From 731c067d377b3674948d0533bbba4247110d4b05 Mon Sep 17 00:00:00 2001 From: stevo89519 Date: Fri, 17 Jan 2025 14:33:58 -0500 Subject: [PATCH 2/5] IWF-439: Add comments for integration test workflows --- integ/workflow/any_command_close/routers.go | 7 ++++--- integ/workflow/any_command_combination/routers.go | 4 +--- integ/workflow/any_timer_signal/routers.go | 7 +++---- integ/workflow/conditional_close/routers.go | 8 +++----- integ/workflow/deadend/routers.go | 2 +- integ/workflow/interstate/routers.go | 2 +- 6 files changed, 13 insertions(+), 17 deletions(-) diff --git a/integ/workflow/any_command_close/routers.go b/integ/workflow/any_command_close/routers.go index 311ee7ef..aad76e99 100644 --- a/integ/workflow/any_command_close/routers.go +++ b/integ/workflow/any_command_close/routers.go @@ -42,8 +42,8 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_start"]++ - // Starting the first state, return trigger signals if req.GetWorkflowStateId() == State1 { + // Proceed after either signal is received c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ SignalCommands: []iwfidl.SignalCommand{ @@ -61,8 +61,8 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { }) return } - // Starting the second state, return "all completed" if req.GetWorkflowStateId() == State2 { + // Go straight to the decide methods without any commands c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ DeciderTriggerType: iwfidl.ALL_COMMAND_COMPLETED.Ptr(), @@ -86,11 +86,11 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_decide"]++ - // Trigger signals and move to next state if req.GetWorkflowStateId() == State1 { signalResults := req.GetCommandResults() h.invokeData["signalCommandResultsLength"] = len(signalResults.SignalResults) + // Trigger signals h.invokeData["signalChannelName0"] = signalResults.SignalResults[0].GetSignalChannelName() h.invokeData["signalCommandId0"] = signalResults.SignalResults[0].GetCommandId() h.invokeData["signalStatus0"] = signalResults.SignalResults[0].GetSignalRequestStatus() @@ -100,6 +100,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { h.invokeData["signalStatus1"] = signalResults.SignalResults[1].GetSignalRequestStatus() h.invokeData["signalValue1"] = signalResults.SignalResults[1].GetSignalValue() + // Move to State 2 c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ NextStates: []iwfidl.StateMovement{ diff --git a/integ/workflow/any_command_combination/routers.go b/integ/workflow/any_command_combination/routers.go index 612077e4..d784230c 100644 --- a/integ/workflow/any_command_combination/routers.go +++ b/integ/workflow/any_command_combination/routers.go @@ -89,7 +89,6 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_start"]++ - // Starting the first state if req.GetWorkflowStateId() == State1 { // If the state has already retried an invalid command, return trigger signals and completion metrics if h.hasS1RetriedForInvalidCommandId { @@ -130,7 +129,6 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { return } - // Starting the second state if req.GetWorkflowStateId() == State2 { // If the state has already retried an invalid command, return signals and completion metrics if h.hasS2RetriedForInvalidCommandId { @@ -185,7 +183,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_decide"]++ - // Trigger signals and move to next state + // Trigger signals and move to State 2 if req.GetWorkflowStateId() == State1 { h.invokeData["s1_commandResults"] = req.GetCommandResults() diff --git a/integ/workflow/any_timer_signal/routers.go b/integ/workflow/any_timer_signal/routers.go index 26a3bfde..fbba3dc3 100644 --- a/integ/workflow/any_timer_signal/routers.go +++ b/integ/workflow/any_timer_signal/routers.go @@ -42,7 +42,6 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_start"]++ - // Starting the first state if req.GetWorkflowStateId() == State1 { var timerCommands []iwfidl.TimerCommand context := req.GetContext() @@ -72,8 +71,8 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { return } - // Starting the second state, return "all completed" if req.GetWorkflowStateId() == State2 { + // Go straight to the decide methods without any commands c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ DeciderTriggerType: iwfidl.ALL_COMMAND_COMPLETED.Ptr(), @@ -101,14 +100,14 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { var movements []iwfidl.StateMovement context := req.GetContext() - // On first state attempt, trigger signals and stay on the first state + // On first State 1 attempt, trigger signals and stay on the first state if context.GetStateExecutionId() == State1+"-"+"1" { h.invokeData["signalChannelName1"] = signalResults.SignalResults[0].GetSignalChannelName() h.invokeData["signalCommandId1"] = signalResults.SignalResults[0].GetCommandId() h.invokeData["signalStatus1"] = signalResults.SignalResults[0].GetSignalRequestStatus() movements = []iwfidl.StateMovement{{StateId: State1}} } else { - // After the first state attempt, trigger signals and move to next state + // After the first State 1 attempt, trigger signals and move to next state h.invokeData["signalChannelName2"] = signalResults.SignalResults[0].GetSignalChannelName() h.invokeData["signalCommandId2"] = signalResults.SignalResults[0].GetCommandId() h.invokeData["signalStatus2"] = signalResults.SignalResults[0].GetSignalRequestStatus() diff --git a/integ/workflow/conditional_close/routers.go b/integ/workflow/conditional_close/routers.go index 2d693116..1b0c9522 100644 --- a/integ/workflow/conditional_close/routers.go +++ b/integ/workflow/conditional_close/routers.go @@ -67,10 +67,8 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_start"]++ - // Starting the first state if req.GetWorkflowStateId() == State1 { - - // Return channel name + // Proceed when channel is published to cmdReq := &iwfidl.CommandRequest{ InterStateChannelCommands: []iwfidl.InterStateChannelCommand{ { @@ -81,8 +79,8 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { } input := req.GetStateInput() - // Return signal instead if input.GetData() == "use-signal-channel" { + // Proceed when signal is published to cmdReq = &iwfidl.CommandRequest{ SignalCommands: []iwfidl.SignalCommand{ { @@ -121,7 +119,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { // Wait for 3 seconds so that the channel can have a new message time.Sleep(time.Second * 3) } else if context.GetStateExecutionId() == "S1-3" { - // send internal channel message within the state execution + // Send internal channel message within the state execution // and expecting the messages are processed by the conditional check internalChanPub = []iwfidl.InterStateChannelPublishing{ { diff --git a/integ/workflow/deadend/routers.go b/integ/workflow/deadend/routers.go index ab9f91e4..6356dfd5 100644 --- a/integ/workflow/deadend/routers.go +++ b/integ/workflow/deadend/routers.go @@ -46,7 +46,7 @@ func (h *handler) ApiV1WorkflowWorkerRpc(c *gin.Context) { } if req.RpcName == RPCTriggerState { - // Move to first state + // Move to State 1 c.JSON(http.StatusOK, iwfidl.WorkflowWorkerRpcResponse{ StateDecision: &iwfidl.StateDecision{NextStates: []iwfidl.StateMovement{ { diff --git a/integ/workflow/interstate/routers.go b/integ/workflow/interstate/routers.go index 1caa48ea..0656b558 100644 --- a/integ/workflow/interstate/routers.go +++ b/integ/workflow/interstate/routers.go @@ -128,7 +128,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { if req.GetWorkflowType() == WorkflowType { h.invokeHistory[req.GetWorkflowStateId()+"_decide"]++ if req.GetWorkflowStateId() == State1 { - // First state requires no pre-reqs + // State 1 requires no pre-reqs // Move to state 21 & 22: // 21 - Will wait for channel 1 // 22 - Will wait 3 seconds then publish to channel 1 From 7cbfdf13f21dcb3ea36b643b5b81ac0c3b40539a Mon Sep 17 00:00:00 2001 From: stevo89519 Date: Fri, 17 Jan 2025 16:15:34 -0500 Subject: [PATCH 3/5] IWF-439: Add comments for integration test workflows --- integ/workflow/skipstart/routers.go | 10 ++++++++++ integ/workflow/timer/routers.go | 10 ++++++++++ integ/workflow/wait_for_state_completion/routers.go | 10 ++++++++++ .../wf_execute_api_fail_and_proceed/routers.go | 9 +++++++++ integ/workflow/wf_force_fail/routers.go | 7 +++++++ integ/workflow/wf_state_api_fail/routers.go | 6 ++++++ .../workflow/wf_state_api_fail_and_proceed/routers.go | 6 ++++++ integ/workflow/wf_state_api_timeout/routers.go | 7 +++++++ 8 files changed, 65 insertions(+) diff --git a/integ/workflow/skipstart/routers.go b/integ/workflow/skipstart/routers.go index 8ce303d1..3b9b4056 100644 --- a/integ/workflow/skipstart/routers.go +++ b/integ/workflow/skipstart/routers.go @@ -8,6 +8,16 @@ import ( "net/http" ) +/** + * This test workflow has 2 states, using REST controller to implement the workflow directly. + * + * State1: + * - Wait until is skipped. + * - Execute method will go to State2 + * State2: + * - Wait until is skipped. + * - Execute method will gracefully complete workflow + */ const ( WorkflowType = "skipstart" State1 = "S1" diff --git a/integ/workflow/timer/routers.go b/integ/workflow/timer/routers.go index b1dba97f..d324dadc 100644 --- a/integ/workflow/timer/routers.go +++ b/integ/workflow/timer/routers.go @@ -13,6 +13,16 @@ import ( "github.com/indeedeng/iwf/service" ) +/** + * This test workflow has 2 states, using REST controller to implement the workflow directly. + * + * State1: + * - Has 3 timers (10s, 1d, 1y) before executing state + * - Execute method will go to State2 + * State2: + * - Waits on nothing. Will execute momentarily + * - Execute method will gracefully complete workflow + */ const ( WorkflowType = "timer" State1 = "S1" diff --git a/integ/workflow/wait_for_state_completion/routers.go b/integ/workflow/wait_for_state_completion/routers.go index 4e306404..41b8c19b 100644 --- a/integ/workflow/wait_for_state_completion/routers.go +++ b/integ/workflow/wait_for_state_completion/routers.go @@ -13,6 +13,16 @@ import ( "github.com/indeedeng/iwf/service" ) +/** + * This test workflow has 2 states, using REST controller to implement the workflow directly. + * + * State1: + * - 10-second delay is added before executing state + * - Execute method will go to State2 + * State2: + * - Waits on nothing. Will execute momentarily + * - Execute method will gracefully complete workflow + */ const ( WorkflowType = "wait_for_state_completion" State1 = "S1" diff --git a/integ/workflow/wf_execute_api_fail_and_proceed/routers.go b/integ/workflow/wf_execute_api_fail_and_proceed/routers.go index 6026c2b0..6ec3a201 100644 --- a/integ/workflow/wf_execute_api_fail_and_proceed/routers.go +++ b/integ/workflow/wf_execute_api_fail_and_proceed/routers.go @@ -10,6 +10,15 @@ import ( "github.com/indeedeng/iwf/integ/workflow/common" ) +/** + * This test workflow has one state, using REST controller to implement the workflow directly. + * + * State1: + * - WaitUntil method is skipped + * - Execute method will intentionally fail + * StateRecover: + * - Execute method will gracefully complete workflow + */ const ( WorkflowType = "wf_execute_api_fail_and_proceed" State1 = "S1" diff --git a/integ/workflow/wf_force_fail/routers.go b/integ/workflow/wf_force_fail/routers.go index 8f54ade1..107cbce7 100644 --- a/integ/workflow/wf_force_fail/routers.go +++ b/integ/workflow/wf_force_fail/routers.go @@ -9,6 +9,13 @@ import ( "net/http" ) +/** + * This test workflow has one state, using REST controller to implement the workflow directly. + * + * State1: + * - WaitUntil method does nothing + * - Execute method will intentionally force-fail + */ const ( WorkflowType = "wf_force_fail" State1 = "S1" diff --git a/integ/workflow/wf_state_api_fail/routers.go b/integ/workflow/wf_state_api_fail/routers.go index 2c06c4cc..10571fa1 100644 --- a/integ/workflow/wf_state_api_fail/routers.go +++ b/integ/workflow/wf_state_api_fail/routers.go @@ -8,6 +8,12 @@ import ( "net/http" ) +/** + * This test workflow has one state, using REST controller to implement the workflow directly. + * + * State1: + * - The state will fail and exit + */ const ( WorkflowType = "wf_state_api_fail" State1 = "S1" diff --git a/integ/workflow/wf_state_api_fail_and_proceed/routers.go b/integ/workflow/wf_state_api_fail_and_proceed/routers.go index 5313a45e..4109f2d8 100644 --- a/integ/workflow/wf_state_api_fail_and_proceed/routers.go +++ b/integ/workflow/wf_state_api_fail_and_proceed/routers.go @@ -10,6 +10,12 @@ import ( "github.com/indeedeng/iwf/integ/workflow/common" ) +/** + * This test workflow has one state, using REST controller to implement the workflow directly. + * + * State1: + * - The state will fail and proceed to StateRecover which will gracefully complete workflow + */ const ( WorkflowType = "wf_state_api_fail_and_proceed" State1 = "S1" diff --git a/integ/workflow/wf_state_api_timeout/routers.go b/integ/workflow/wf_state_api_timeout/routers.go index 53ab1ec3..09172f8e 100644 --- a/integ/workflow/wf_state_api_timeout/routers.go +++ b/integ/workflow/wf_state_api_timeout/routers.go @@ -9,6 +9,13 @@ import ( "time" ) +/** + * This test workflow has one state, using REST controller to implement the workflow directly. + * + * State1: + * - Timeout is set for 10s + * - Waits for 30s to invoke a timeout exception + */ const ( WorkflowType = "wf_state_api_timeout" State1 = "S1" From ff994be3fa07e59f3fd21e1b8743ae7b5e172c14 Mon Sep 17 00:00:00 2001 From: stevo89519 Date: Fri, 17 Jan 2025 17:27:19 -0500 Subject: [PATCH 4/5] IWF-439: Add comments for integration test workflows --- integ/workflow/any_command_close/routers.go | 10 ++++++++++ .../workflow/any_command_combination/routers.go | 14 ++++++++++++-- integ/workflow/any_timer_signal/routers.go | 10 ++++++++++ integ/workflow/basic/routers.go | 10 ++++++++++ integ/workflow/conditional_close/routers.go | 8 ++++++++ integ/workflow/deadend/routers.go | 11 +++++++++++ integ/workflow/headers/routers.go | 7 +++++++ integ/workflow/interstate/routers.go | 16 ++++++++++++++++ .../routers.go | 2 +- 9 files changed, 85 insertions(+), 3 deletions(-) diff --git a/integ/workflow/any_command_close/routers.go b/integ/workflow/any_command_close/routers.go index aad76e99..3b00cbd5 100644 --- a/integ/workflow/any_command_close/routers.go +++ b/integ/workflow/any_command_close/routers.go @@ -10,6 +10,16 @@ import ( "net/http" ) +/** + * This test workflow has 2 states, using REST controller to implement the workflow directly. + * + * State1: + * - WaitUntil wait until a signal is received + * - Execute method will fire the signal and move the State2 + * State2: + * - Waits on nothing. Will execute momentarily + * - Execute method will gracefully complete workflow + */ const ( WorkflowType = "any_command_close" State1 = "S1" diff --git a/integ/workflow/any_command_combination/routers.go b/integ/workflow/any_command_combination/routers.go index d784230c..fc497198 100644 --- a/integ/workflow/any_command_combination/routers.go +++ b/integ/workflow/any_command_combination/routers.go @@ -11,6 +11,16 @@ import ( "time" ) +/** + * This test workflow has 2 states, using REST controller to implement the workflow directly. + * + * State1: + * - WaitUntil will fail its first attempt and then retry which will proceed when a combination is completed + * - Execute method will invoke the combination and move the State2 + * State2: + * - WaitUntil will fail its first attempt and then retry which will proceed when a combination is completed + * - Execute method will invoke the combination and gracefully complete workflow + */ const ( WorkflowType = "any_command_combination" State1 = "S1" @@ -90,7 +100,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { h.invokeHistory[req.GetWorkflowStateId()+"_start"]++ if req.GetWorkflowStateId() == State1 { - // If the state has already retried an invalid command, return trigger signals and completion metrics + // If the state has already retried an invalid command, proceed on combination completed if h.hasS1RetriedForInvalidCommandId { startResp := iwfidl.WorkflowStateStartResponse{ CommandRequest: &iwfidl.CommandRequest{ @@ -198,7 +208,7 @@ func (h *handler) ApiV1WorkflowStateDecide(c *gin.Context) { }) return } else if req.GetWorkflowStateId() == State2 { - // Fire signals and move to completion + // Trigger data and move to completion h.invokeData["s2_commandResults"] = req.GetCommandResults() c.JSON(http.StatusOK, iwfidl.WorkflowStateDecideResponse{ StateDecision: &iwfidl.StateDecision{ diff --git a/integ/workflow/any_timer_signal/routers.go b/integ/workflow/any_timer_signal/routers.go index fbba3dc3..00249b4b 100644 --- a/integ/workflow/any_timer_signal/routers.go +++ b/integ/workflow/any_timer_signal/routers.go @@ -11,6 +11,16 @@ import ( "time" ) +/** + * This test workflow has 2 states, using REST controller to implement the workflow directly. + * + * State1: + * - WaitUntil will wait for the signals to trigger. + * - Execute method will trigger signals and retry State1 once, then trigger signals and move the State2 + * State2: + * - Waits on nothing. Will execute momentarily + * - Execute method will gracefully complete workflow + */ const ( WorkflowType = "any_timer_signal" State1 = "S1" diff --git a/integ/workflow/basic/routers.go b/integ/workflow/basic/routers.go index 2fa46156..6102ae2b 100644 --- a/integ/workflow/basic/routers.go +++ b/integ/workflow/basic/routers.go @@ -8,6 +8,16 @@ import ( "net/http" ) +/** + * This test workflow has 2 states, using REST controller to implement the workflow directly. + * + * State1: + * - Waits on nothing. Will execute momentarily + * - Execute method will move to State2 + * State2: + * - Waits on nothing. Will execute momentarily + * - Execute method will gracefully complete workflow + */ const ( WorkflowType = "basic" State1 = "S1" diff --git a/integ/workflow/conditional_close/routers.go b/integ/workflow/conditional_close/routers.go index 1b0c9522..3d4f06d1 100644 --- a/integ/workflow/conditional_close/routers.go +++ b/integ/workflow/conditional_close/routers.go @@ -10,6 +10,14 @@ import ( "time" ) +/** + * This test workflow has 1 state, using REST controller to implement the workflow directly. + * + * State1: + * - WaitUntil will proceed when the channel or signal is published to + * - Execute method will continuously retry State1 until the 3rd attempt which will send a message to the channel or + * signal, making the state empty and force-complete. + */ const ( WorkflowType = "conditional_close" RpcPublishInternalChannel = "publish_internal_channel" diff --git a/integ/workflow/deadend/routers.go b/integ/workflow/deadend/routers.go index 6356dfd5..68709ecc 100644 --- a/integ/workflow/deadend/routers.go +++ b/integ/workflow/deadend/routers.go @@ -9,6 +9,17 @@ import ( "net/http" ) +/** + * This test workflow has 3 states, using REST controller to implement the workflow directly. + * + * RPCWriteData: + * - WaitUntil will upsert data attributes + * RPCTriggerState: + * - WaitUntil will move to State1 + * State1: + * - WaitUntil is skipped + * - Execute method will put the state into a dead-end. + */ const ( WorkflowType = "deadend" RPCTriggerState = "test-RPCTriggerState" diff --git a/integ/workflow/headers/routers.go b/integ/workflow/headers/routers.go index b291bca0..1a2bab70 100644 --- a/integ/workflow/headers/routers.go +++ b/integ/workflow/headers/routers.go @@ -8,6 +8,13 @@ import ( "net/http" ) +/** + * This test workflow has 1 state, using REST controller to implement the workflow directly. + * + * State1: + * - WaitUntil method does nothing + * - Execute method will gracefully complete workflow + */ const ( WorkflowType = "headers" State1 = "S1" diff --git a/integ/workflow/interstate/routers.go b/integ/workflow/interstate/routers.go index 0656b558..8fab420c 100644 --- a/integ/workflow/interstate/routers.go +++ b/integ/workflow/interstate/routers.go @@ -10,6 +10,22 @@ import ( "time" ) +/** + * This test workflow has four states, using REST controller to implement the workflow directly. + * + * State1: + * - WaitUntil method does nothing + * - Execute method will move to State21 & State22: + * State21: + * - WaitUntil will proceed once channel1 has been published to + * - Execute method will move to State31: + * State22: + * - WaitUntil delays 2 seconds then publishes on the first channel + * - Execute method will delay 2s publish on channel2 & end in a dead-end + * State31: + * - WaitUntil will proceed once channel2 has been published to + * - Execute method will gracefully complete workflow + */ const ( WorkflowType = "interstate" State1 = "S1" diff --git a/integ/workflow/wf_state_options_search_attributes_loading/routers.go b/integ/workflow/wf_state_options_search_attributes_loading/routers.go index 8e4917e0..e3fe6575 100644 --- a/integ/workflow/wf_state_options_search_attributes_loading/routers.go +++ b/integ/workflow/wf_state_options_search_attributes_loading/routers.go @@ -12,7 +12,7 @@ import ( ) /** - * This test workflow has four states, using REST controller to implement the workflow directly. + * This test workflow has five states, using REST controller to implement the workflow directly. * * State1: * - WaitUntil method does nothing From af57a96f133de704fef9e0cbd903f49762c2035e Mon Sep 17 00:00:00 2001 From: stevo89519 Date: Fri, 17 Jan 2025 18:42:21 -0500 Subject: [PATCH 5/5] IWF-439: Add comments for integration test workflows --- integ/workflow/interstate/routers.go | 6 ++-- integ/workflow/locking/routers.go | 13 +++++++++ integ/workflow/parallel/routers.go | 28 +++++++++++++++++++ integ/workflow/persistence/routers.go | 13 +++++++++ .../persistence_loading_policy/routers.go | 10 +++++++ integ/workflow/rpc/routers.go | 10 +++++++ integ/workflow/signal/routers.go | 10 +++++++ 7 files changed, 87 insertions(+), 3 deletions(-) diff --git a/integ/workflow/interstate/routers.go b/integ/workflow/interstate/routers.go index 8fab420c..f72b303f 100644 --- a/integ/workflow/interstate/routers.go +++ b/integ/workflow/interstate/routers.go @@ -20,8 +20,8 @@ import ( * - WaitUntil will proceed once channel1 has been published to * - Execute method will move to State31: * State22: - * - WaitUntil delays 2 seconds then publishes on the first channel - * - Execute method will delay 2s publish on channel2 & end in a dead-end + * - WaitUntil will delay 2s then publish on channel1 + * - Execute method will delay 2s then publish on channel2 & end in a dead-end * State31: * - WaitUntil will proceed once channel2 has been published to * - Execute method will gracefully complete workflow @@ -111,7 +111,7 @@ func (h *handler) ApiV1WorkflowStateStart(c *gin.Context) { return } - // Wait 2 seconds then publish on the first channel + // Wait 2 seconds then publish on channel1 if req.GetWorkflowStateId() == State22 { time.Sleep(time.Second * 2) c.JSON(http.StatusOK, iwfidl.WorkflowStateStartResponse{ diff --git a/integ/workflow/locking/routers.go b/integ/workflow/locking/routers.go index 0bb13920..5ccb6c17 100644 --- a/integ/workflow/locking/routers.go +++ b/integ/workflow/locking/routers.go @@ -13,6 +13,19 @@ import ( "time" ) +/** + * This test workflow has three states, using REST controller to implement the workflow directly. + * + * State1: + * - WaitUntil method does nothing + * - Execute method will move to State Waiting, and 10 instances of State 2 + * State2: + * - WaitUntil update SA + * - Execute method will update data objects and will gracefully complete workflow + * StateWaiting: + * - WaitUntil will proceed once the internal channel has been published to + * - Execute method will gracefully complete workflow + */ const ( WorkflowType = "locking" State1 = "S1" diff --git a/integ/workflow/parallel/routers.go b/integ/workflow/parallel/routers.go index c1220828..520310cf 100644 --- a/integ/workflow/parallel/routers.go +++ b/integ/workflow/parallel/routers.go @@ -10,6 +10,34 @@ import ( "time" ) +/** + * This test workflow has eight states, using REST controller to implement the workflow directly. + * + * State1: + * - WaitUntil method does nothing + * - Execute method delays 1s then moves to State11, State12, & State13 + * State11: + * - WaitUntil method does nothing + * - Execute method delays 2s then moves to State111 & State112 + * State12: + * - WaitUntil method does nothing + * - Execute method delays 2s then moves to State121 & State122 + * State13: + * - WaitUntil method does nothing + * - Execute method will delay 1s then gracefully complete workflow + * State111: + * - WaitUntil method does nothing + * - Execute method will gracefully complete workflow + * State112: + * - WaitUntil method does nothing + * - Execute method will gracefully complete workflow + * State121: + * - WaitUntil method does nothing + * - Execute method will gracefully complete workflow + * State122: + * - WaitUntil method does nothing + * - Execute method will gracefully complete workflow + */ const ( WorkflowType = "parallel" State1 = "S1" diff --git a/integ/workflow/persistence/routers.go b/integ/workflow/persistence/routers.go index 5587eca1..9d58e7dc 100644 --- a/integ/workflow/persistence/routers.go +++ b/integ/workflow/persistence/routers.go @@ -10,6 +10,19 @@ import ( "net/http" ) +/** + * This test workflow has three states, using REST controller to implement the workflow directly. + * + * State1: + * - WaitUntil method will update DA, SA, & SL + * - Execute method will move to State2 with partially loaded data + * State2: + * - WaitUntil method will store attribute data + * - Execute method will move to State3 with partially loaded data + * State3: + * - WaitUntil method performs some attribute checks + * - Execute method performs checks on the attribute data and then gracefully completes the workflow + */ const ( WorkflowType = "persistence" State1 = "S1" diff --git a/integ/workflow/persistence_loading_policy/routers.go b/integ/workflow/persistence_loading_policy/routers.go index e632df56..8db274d6 100644 --- a/integ/workflow/persistence_loading_policy/routers.go +++ b/integ/workflow/persistence_loading_policy/routers.go @@ -12,6 +12,16 @@ import ( "net/http" ) +/** + * This test workflow has two states, using REST controller to implement the workflow directly. + * + * State1: + * - WaitUntil skipped + * - Execute method verifies the loaded attributes then moves to a dead-end. + * State2: + * - WaitUntil method verifies the loaded attributes + * - Execute method verifies the loaded attributes then gracefully completes the workflow + */ const ( WorkflowType = "persistence_loading_policy" State1 = "S1" diff --git a/integ/workflow/rpc/routers.go b/integ/workflow/rpc/routers.go index 57bf8640..b27a4012 100644 --- a/integ/workflow/rpc/routers.go +++ b/integ/workflow/rpc/routers.go @@ -10,6 +10,16 @@ import ( "net/http" ) +/** + * This test workflow has two states, using REST controller to implement the workflow directly. + * + * State1: + * - WaitUntil updates attribute data and data objects and then waits until the channel has been published to + * - Execute method moves to State2 + * State2: + * - WaitUntil method does nothing + * - Execute method will gracefully complete workflow + */ const ( WorkflowType = "rpc" State1 = "S1" diff --git a/integ/workflow/signal/routers.go b/integ/workflow/signal/routers.go index 4b35dbe5..1c39c5b7 100644 --- a/integ/workflow/signal/routers.go +++ b/integ/workflow/signal/routers.go @@ -12,6 +12,16 @@ import ( "net/http" ) +/** + * This test workflow has two states, using REST controller to implement the workflow directly. + * + * State1: + * - WaitUntil waits until 4 signals are received + * - Execute method publishes the 4 signals & moves to State2 + * State2: + * - WaitUntil method does nothing + * - Execute method will gracefully complete workflow + */ const ( WorkflowType = "signal" State1 = "S1"