503
}
504
505
>
func (e *Engine) newExecution(key chasm.ExecutionKey) *execution {
test_engine.go
506
>
// bsMu (backend state mutex) guards transitionCount and execState, which are shared
507
>
// across handler closures. It is separate from MockNodeBackend's internal mu to avoid deadlocks.
508
>
var (
509
>
bsMu sync.Mutex
510
>
transitionCount int64 = 1
511
>
execState = persistencespb.WorkflowExecutionState{
512
>
State: enumsspb.WORKFLOW_EXECUTION_STATE_CREATED,
513
>
Status: enumspb.WORKFLOW_EXECUTION_STATUS_RUNNING,
514
>
}
515
>
)
516
>
517
>
backend := &chasm.MockNodeBackend{
518
>
// NextTransitionCount increments on every CloseTransaction call, matching
519
>
// the real engine's per transition monotonic counter.
520
>
HandleNextTransitionCount: func() int64 {
521
>
bsMu.Lock()
522
>
defer bsMu.Unlock()
523
>
transitionCount++
524
>
return transitionCount
525
>
},
526
// CurrentVersionedTransition reflects the latest committed transition count.
527
>
HandleCurrentVersionedTransition: func() *persistencespb.VersionedTransition {
test_engine.go
528
>
bsMu.Lock()
529
>
defer bsMu.Unlock()
530
>
return &persistencespb.VersionedTransition{
531
>
NamespaceFailoverVersion: 1,
532
>
TransitionCount: transitionCount,
533
>
}
534
>
},
535
>
HandleGetCurrentVersion: func() int64 { return 1 },
536
>
HandleGetWorkflowKey: func() definition.WorkflowKey {
537
>
return definition.NewWorkflowKey(key.NamespaceID, key.BusinessID, key.RunID)
538
>
},
539
>
HandleIsWorkflow: func() bool { return false },
540
// GetExecutionState returns the current lifecycle state, which CloseTransaction
541
// uses to decide whether to call UpdateWorkflowStateStatus on the backend.
542
>
HandleGetExecutionState: func() *persistencespb.WorkflowExecutionState {
test_engine.go
543
>
bsMu.Lock()
544
>
defer bsMu.Unlock()
545
>
return &persistencespb.WorkflowExecutionState{
546
>
State: execState.State,
547
>
Status: execState.Status,
548
>
}
549
>
},
550
// UpdateWorkflowStateStatus is called by CloseTransaction when the root
551
// component's LifecycleState changes from Running to Completed, Failed, or Terminated.
552
>
HandleUpdateWorkflowStateStatus: func(state enumsspb.WorkflowExecutionState, status enumspb.WorkflowExecutionStatus) (bool, error) {
test_engine.go
553
>
bsMu.Lock()
554
>
defer bsMu.Unlock()
555
>
changed := execState.State != state || execState.Status != status
556
>
execState.State = state
557
>
execState.Status = status
558
>
return changed, nil
559
>
},
560
}
562
>
key: key,
563
>
backend: backend,
564
>
node: chasm.NewEmptyTree(
565
>
e.registry,
566
>
e.timeSource,
567
>
backend,
568
>
chasm.DefaultPathEncoder,
569
>
e.logger,
570
>
e.metrics,
571
>
),
572
>
}
573
}
574
575
// executionForRef looks up an execution by the ref's RunID when present, or falls back
576
// to the current run for the business ID when RunID is empty.
577
>
func (e *Engine) executionForRef(ref chasm.ComponentRef) (*execution, error) {
test_engine.go
578
>
if ref.RunID != "" {
579
exec, ok := e.allExecutions[newRunKey(ref.ExecutionKey)]
580
if !ok {