Repository: hashicorp/vault
File: physical/raft/raft_autopilot.go (Go)

Code before:
	if ac.DeadServerLastContactThreshold, err = parseutil.ParseDurationSecond(conf["dead_server_last_contact_threshold"]); err != nil {
		return err
	}
	if ac.ServerStabilizationTime, err = parseutil.ParseDurationSecond(conf["server_stabilization_time"]); err != nil {
		return err
	}

	return nil
}

// FollowerState represents the information about peer that the leader tracks.
type FollowerState struct {
	AppliedIndex    uint64
	LastHeartbeat   time.Time
	LastTerm        uint64
	IsDead          *atomic.Bool
	DesiredSuffrage string
	Version         string
	UpgradeVersion  string
	RedundancyZone  string
}

// partialCopy returns a partial copy of the follower state.
// This copy uses the same pointer to the IsDead
// atomic field. We need to do this to ensure that
// an update of the IsDead boolean will still be
// accessible in a copied state.
func (f *FollowerState) partialCopy() *FollowerState {
	return &FollowerState{
		AppliedIndex:    f.AppliedIndex,
		LastHeartbeat:   f.LastHeartbeat,
		LastTerm:        f.LastTerm,
		IsDead:          f.IsDead,
		DesiredSuffrage: f.DesiredSuffrage,
		Version:         f.Version,
		UpgradeVersion:  f.UpgradeVersion,
		RedundancyZone:  f.RedundancyZone,
	}
}

// PersistedFollowerState holds the information that gets persisted to storage
type PersistedFollowerState struct {
	Version        string `json:"version"`
	UpgradeVersion string `json:"upgrade_version"`
}

type PersistedFollowerStates struct {
	l      sync.RWMutex
	States map[string]PersistedFollowerState
}


Review comment (suggestion):
Mega-nit alert 🚨 

```suggestion
	// since we set it for every node in the cluster during post-unseal.
```

Code after:
	}
	if ac.DeadServerLastContactThreshold, err = parseutil.ParseDurationSecond(conf["dead_server_last_contact_threshold"]); err != nil {
		return err
	}
	if ac.ServerStabilizationTime, err = parseutil.ParseDurationSecond(conf["server_stabilization_time"]); err != nil {
		return err
	}

	return nil
}

// FollowerState represents the information about peer that the leader tracks.
type FollowerState struct {
	AppliedIndex    uint64
	LastHeartbeat   time.Time
	LastTerm        uint64
	IsDead          *atomic.Bool
	DesiredSuffrage string
	Version         string
	UpgradeVersion  string
	RedundancyZone  string
}

func (f *FollowerState) neverSentHeartbeat() bool {
	// We can't use LastHeartbeat to determine if the node has been contacted,
	// since we set it for every node in the cluster during post-unseal
	// Instead, check if the node has reported any applied index or term.
	// These will both be 0 if the node has never sent an echo.
	return f.LastTerm == 0 && f.AppliedIndex == 0
}

// partialCopy returns a partial copy of the follower state.
// This copy uses the same pointer to the IsDead
// atomic field. We need to do this to ensure that
// an update of the IsDead boolean will still be
// accessible in a copied state.
func (f *FollowerState) partialCopy() *FollowerState {
	return &FollowerState{
		AppliedIndex:    f.AppliedIndex,
		LastHeartbeat:   f.LastHeartbeat,
		LastTerm:        f.LastTerm,
		IsDead:          f.IsDead,
		DesiredSuffrage: f.DesiredSuffrage,
		Version:         f.Version,
		UpgradeVersion:  f.UpgradeVersion,
		RedundancyZone:  f.RedundancyZone,
	}
}

// PersistedFollowerState holds the information that gets persisted to storage
type PersistedFollowerState struct {