Copilot commented on code in PR #1100:
URL: 
https://github.com/apache/incubator-seata-go/pull/1100#discussion_r3037032680


##########
pkg/saga/statemachine/engine/core/process_ctrl_statemachine_engine.go:
##########
@@ -412,11 +412,11 @@ func (p ProcessCtrlStateMachineEngine) 
createMachineInstance(stateMachineName st
                        "StateMachine ["+stateMachineName+"] is not exists", 
nil)
        }
 
-       stateMachineInstance := statelang.NewStateMachineInstanceImpl()
-       stateMachineInstance.SetStateMachine(stateMachine)
-       stateMachineInstance.SetTenantID(tenantId)
-       stateMachineInstance.SetBusinessKey(businessKey)
-       stateMachineInstance.SetStartParams(startParams)
+       stateMachineInstance := statelang.NewStateMachineInstance()
+       stateMachineInstance.StateMachine = stateMachine

Review Comment:
   `createMachineInstance` assigns `StateMachine` but never populates 
`MachineID`. Previously `SetStateMachine(...)` also set `MachineID` from 
`stateMachine.ID()`, and the DB store insert/update paths rely on `MachineID` 
being non-empty. Set `MachineID` when attaching the state machine (e.g., use 
the new `SetStateMachineAndID` helper or assign `MachineID = 
stateMachine.ID()`), otherwise persisted instances may have blank machine_id 
and later reload/lookup can fail.
   ```suggestion
        stateMachineInstance.StateMachine = stateMachine
        stateMachineInstance.MachineID = stateMachine.ID()
   ```



##########
pkg/saga/statemachine/store/db/statelog.go:
##########
@@ -569,33 +569,33 @@ func (s *StateLogStore) isUpdateMode(stateInstance 
statelang.StateInstance, cont
        return false, nil
 }
 
-func (s *StateLogStore) generateRetryStateInstanceId(stateInstance 
statelang.StateInstance) string {
-       originalStateInstId := stateInstance.StateIDRetriedFor()
+func (s *StateLogStore) generateRetryStateInstanceId(stateInstance 
*statelang.StateInstance) string {
+       originalStateInstId := stateInstance.StateIDRetriedFor
        maxIndex := 1
-       machineInstance := stateInstance.StateMachineInstance()
+       machineInstance := stateInstance.StateMachineInstance
        originalStateInst := machineInstance.State(originalStateInstId)
-       for originalStateInst.StateIDRetriedFor() != "" {
-               originalStateInst = 
machineInstance.State(originalStateInst.StateIDRetriedFor())
-               idIndex := s.getIdIndex(originalStateInst.ID(), ".")
+       for originalStateInst.StateIDRetriedFor != "" {
+               originalStateInst = 
machineInstance.State(originalStateInst.StateIDRetriedFor)
+               idIndex := s.getIdIndex(originalStateInst.ID, ".")
                if idIndex > maxIndex {
                        maxIndex = idIndex
                }
-               originalStateInstId = originalStateInst.ID()
+               originalStateInstId = originalStateInst.ID
        }
        return fmt.Sprintf("%s.%d", originalStateInstId, maxIndex)
 }

Review Comment:
   `generateRetryStateInstanceId` appears to return duplicate IDs for 
subsequent retries. `getIdIndex` returns the existing numeric suffix (e.g., 1 
for `origin.1`), but this function returns `fmt.Sprintf("%s.%d", 
originalStateInstId, maxIndex)` without incrementing to the next available 
index, and the loop walks *backward* to the original state (which often has no 
suffix). This can cause collisions like repeatedly generating `origin.1` for 
multiple retry attempts. Consider scanning existing retry instances for the 
same origin and returning `maxIndex+1` (or otherwise guaranteeing monotonic 
unique IDs).



##########
pkg/saga/statemachine/store/db/statelog.go:
##########
@@ -891,33 +891,33 @@ func (s *StateLogStore) branchReport(ctx context.Context, 
stateInstance statelan
                err = engExc.NewEngineExecutionException(
                        seataErrors.TransactionErrorCodeBranchReportFailed,
                        fmt.Sprintf("branch report via template failed, 
stateMachine=%s, state=%s, xid=%s, branchId=%d",
-                               
originalStateInst.StateMachineInstance().StateMachine().Name(), 
originalStateInst.Name(), globalTransaction.Xid, branchId),
+                               
originalStateInst.StateMachineInstance.StateMachine.Name(), 
originalStateInst.Name, globalTransaction.Xid, branchId),
                        err,
                )
                return err
        }
        return nil
 }
 
-func (s *StateLogStore) findOutOriginalStateInstanceOfRetryState(stateInstance 
statelang.StateInstance) statelang.StateInstance {
-       stateMap := stateInstance.StateMachineInstance().StateMap()
-       originalStateInst := stateMap[stateInstance.StateIDRetriedFor()]
-       for originalStateInst.StateIDRetriedFor() != "" {
-               originalStateInst = stateMap[stateInstance.StateIDRetriedFor()]
+func (s *StateLogStore) findOutOriginalStateInstanceOfRetryState(stateInstance 
*statelang.StateInstance) *statelang.StateInstance {
+       stateMap := stateInstance.StateMachineInstance.StateMap()
+       originalStateInst := stateMap[stateInstance.StateIDRetriedFor]
+       for originalStateInst.StateIDRetriedFor != "" {
+               originalStateInst = stateMap[stateInstance.StateIDRetriedFor]
        }
        return originalStateInst
 }
 
-func (s *StateLogStore) 
findOutOriginalStateInstanceOfCompensateState(stateInstance 
statelang.StateInstance) statelang.StateInstance {
-       stateMap := stateInstance.StateMachineInstance().StateMap()
-       originalStateInst := stateMap[stateInstance.StateIDCompensatedFor()]
-       for originalStateInst.StateIDRetriedFor() != "" {
-               originalStateInst = stateMap[stateInstance.StateIDRetriedFor()]
+func (s *StateLogStore) 
findOutOriginalStateInstanceOfCompensateState(stateInstance 
*statelang.StateInstance) *statelang.StateInstance {
+       stateMap := stateInstance.StateMachineInstance.StateMap()
+       originalStateInst := stateMap[stateInstance.StateIDCompensatedFor]
+       for originalStateInst.StateIDRetriedFor != "" {
+               originalStateInst = stateMap[stateInstance.StateIDRetriedFor]
        }
        return originalStateInst

Review Comment:
   `findOutOriginalStateInstanceOfCompensateState` has the same retry-chain 
traversal bug as the retry variant: inside the loop it reuses 
`stateInstance.StateIDRetriedFor` instead of progressing with 
`originalStateInst.StateIDRetriedFor`. If the compensated/original instance is 
itself a retry, this can also hang indefinitely. Update the loop to follow 
`originalStateInst.StateIDRetriedFor` (and handle missing keys) so it 
terminates correctly.



##########
pkg/saga/statemachine/store/db/statelog.go:
##########
@@ -891,33 +891,33 @@ func (s *StateLogStore) branchReport(ctx context.Context, 
stateInstance statelan
                err = engExc.NewEngineExecutionException(
                        seataErrors.TransactionErrorCodeBranchReportFailed,
                        fmt.Sprintf("branch report via template failed, 
stateMachine=%s, state=%s, xid=%s, branchId=%d",
-                               
originalStateInst.StateMachineInstance().StateMachine().Name(), 
originalStateInst.Name(), globalTransaction.Xid, branchId),
+                               
originalStateInst.StateMachineInstance.StateMachine.Name(), 
originalStateInst.Name, globalTransaction.Xid, branchId),
                        err,
                )
                return err
        }
        return nil
 }
 
-func (s *StateLogStore) findOutOriginalStateInstanceOfRetryState(stateInstance 
statelang.StateInstance) statelang.StateInstance {
-       stateMap := stateInstance.StateMachineInstance().StateMap()
-       originalStateInst := stateMap[stateInstance.StateIDRetriedFor()]
-       for originalStateInst.StateIDRetriedFor() != "" {
-               originalStateInst = stateMap[stateInstance.StateIDRetriedFor()]
+func (s *StateLogStore) findOutOriginalStateInstanceOfRetryState(stateInstance 
*statelang.StateInstance) *statelang.StateInstance {
+       stateMap := stateInstance.StateMachineInstance.StateMap()
+       originalStateInst := stateMap[stateInstance.StateIDRetriedFor]
+       for originalStateInst.StateIDRetriedFor != "" {
+               originalStateInst = stateMap[stateInstance.StateIDRetriedFor]
        }
        return originalStateInst

Review Comment:
   `findOutOriginalStateInstanceOfRetryState` will loop forever when the 
original instance itself has `StateIDRetriedFor != ""` because the loop 
re-fetches `stateMap[stateInstance.StateIDRetriedFor]` instead of advancing 
using `originalStateInst.StateIDRetriedFor`. This should traverse the retry 
chain via the current `originalStateInst` (and defensively handle missing map 
entries) to avoid infinite loops/hangs during branch reporting.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to