diff --git a/hscontrol/types/node.go b/hscontrol/types/node.go index fe7638c9..2a4e0e7d 100644 --- a/hscontrol/types/node.go +++ b/hscontrol/types/node.go @@ -154,6 +154,16 @@ type Node struct { DeletedAt *time.Time IsOnline *bool `gorm:"-"` + + // Unhealthy excludes the node from primary route election while + // online. Written by the HA prober. Runtime-only. + Unhealthy bool `gorm:"-"` + + // SessionEpoch identifies a poll session. Connect bumps it; a + // Disconnect carrying a stale value is dropped, so a deferred + // disconnect from a previous session cannot overwrite a newer + // Connect. Runtime-only. + SessionEpoch uint64 `gorm:"-"` } type Nodes []*Node diff --git a/hscontrol/types/types_clone.go b/hscontrol/types/types_clone.go index be22b350..163c22c8 100644 --- a/hscontrol/types/types_clone.go +++ b/hscontrol/types/types_clone.go @@ -106,6 +106,8 @@ var _NodeCloneNeedsRegeneration = Node(struct { UpdatedAt time.Time DeletedAt *time.Time IsOnline *bool + Unhealthy bool + SessionEpoch uint64 }{}) // Clone makes a deep copy of PreAuthKey. diff --git a/hscontrol/types/types_view.go b/hscontrol/types/types_view.go index bdbd0f77..6684ecd6 100644 --- a/hscontrol/types/types_view.go +++ b/hscontrol/types/types_view.go @@ -258,7 +258,16 @@ func (v NodeView) DeletedAt() views.ValuePointer[time.Time] { func (v NodeView) IsOnline() views.ValuePointer[bool] { return views.ValuePointerOf(v.ж.IsOnline) } -func (v NodeView) String() string { return v.ж.String() } +// Unhealthy excludes the node from primary route election while +// online. Written by the HA prober. Runtime-only. +func (v NodeView) Unhealthy() bool { return v.ж.Unhealthy } + +// SessionEpoch identifies a poll session. Connect bumps it; a +// Disconnect carrying a stale value is dropped, so a deferred +// disconnect from a previous session cannot overwrite a newer +// Connect. Runtime-only. +func (v NodeView) SessionEpoch() uint64 { return v.ж.SessionEpoch } +func (v NodeView) String() string { return v.ж.String() } // A compilation failure here means this code must be regenerated, with the command at the top of this file. var _NodeViewNeedsRegeneration = Node(struct { @@ -285,6 +294,8 @@ var _NodeViewNeedsRegeneration = Node(struct { UpdatedAt time.Time DeletedAt *time.Time IsOnline *bool + Unhealthy bool + SessionEpoch uint64 }{}) // View returns a read-only view of PreAuthKey.