64 lines
1.3 KiB
Go
64 lines
1.3 KiB
Go
package domain
|
|
|
|
import (
|
|
"errors"
|
|
"math"
|
|
)
|
|
|
|
var (
|
|
ErrInvalidRevision = errors.New("command revision must be nonzero")
|
|
ErrRevisionOverflow = errors.New("command revision overflow")
|
|
ErrStaleRevision = errors.New("stale command revision")
|
|
ErrFutureRevision = errors.New("unexpected future command revision")
|
|
)
|
|
|
|
type CommandRevision uint64
|
|
|
|
const InitialCommandRevision CommandRevision = 1
|
|
|
|
type RevisionRelation uint8
|
|
|
|
const (
|
|
RevisionInvalid RevisionRelation = iota
|
|
RevisionStale
|
|
RevisionCurrent
|
|
RevisionFuture
|
|
)
|
|
|
|
func CompareRevision(current, incoming CommandRevision) RevisionRelation {
|
|
if current == 0 || incoming == 0 {
|
|
return RevisionInvalid
|
|
}
|
|
if incoming < current {
|
|
return RevisionStale
|
|
}
|
|
if incoming > current {
|
|
return RevisionFuture
|
|
}
|
|
return RevisionCurrent
|
|
}
|
|
|
|
func ValidateCurrentRevision(current, incoming CommandRevision) error {
|
|
switch CompareRevision(current, incoming) {
|
|
case RevisionCurrent:
|
|
return nil
|
|
case RevisionStale:
|
|
return ErrStaleRevision
|
|
case RevisionFuture:
|
|
return ErrFutureRevision
|
|
default:
|
|
return ErrInvalidRevision
|
|
}
|
|
}
|
|
|
|
// NextRevision durably orders a new cancel or signal intent.
|
|
func NextRevision(current CommandRevision) (CommandRevision, error) {
|
|
if current == 0 {
|
|
return 0, ErrInvalidRevision
|
|
}
|
|
if current == math.MaxUint64 {
|
|
return 0, ErrRevisionOverflow
|
|
}
|
|
return current + 1, nil
|
|
}
|