583
// It updates the state machine's metadata and marks the entry as dirty in the node's cache.
584
// If the transition fails, the changes are rolled back and no state is mutated.
585
>
func MachineTransition[T any](n *Node, transitionFn func(T) (TransitionOutput, error)) (retErr error) {
tree.go
586
>
if n.cache.deleted {
587
return fmt.Errorf("%w: cannot transition deleted node: %v", ErrStateMachineInvalidState, n.Key)
588
}
589
590
>
data, err := MachineData[T](n)
tree.go
591
>
if err != nil {
592
return err
593
}
594
// Update the transition counts before applying the transition function in case the transition function needs to
595
// generate references to this node.
596
>
n.persistence.TransitionCount++
tree.go
597
>
prevLastUpdatedVersionedTransition := n.persistence.LastUpdateVersionedTransition
598
>
n.persistence.LastUpdateVersionedTransition = &persistencespb.VersionedTransition{
599
>
NamespaceFailoverVersion: n.backend.GetCurrentVersion(),
600
>
// The transition count for the backend is only incremented when closing the current transaction,
601
>
// but any change to state machine node is a state transtion,
602
>
// so we can safely using next transition count here.
603
>
TransitionCount: n.backend.NextTransitionCount(),
604
>
}
605
>
// Rollback on error
606
>
defer func() {
607
>
if retErr != nil {
608
n.persistence.TransitionCount--
609
n.persistence.LastUpdateVersionedTransition = prevLastUpdatedVersionedTransition