types: add ActiveSessions poll session refcount to Node

In-memory only, like SessionEpoch. Generated clone/view regenerated.
This commit is contained in:
Kristoffer Dalby
2026-06-10 12:20:58 +00:00
committed by Kristoffer Dalby
parent 71a4ce3c9f
commit 759381ad78
3 changed files with 32 additions and 8 deletions
+15 -4
View File
@@ -181,10 +181,21 @@ type Node struct {
// 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.
// ActiveSessions counts live poll sessions for this node.
// [State.Connect] increments it and every session release
// ([State.Disconnect]) decrements it, so the node goes offline
// exactly when its last session ends — regardless of the order in
// which overlapping sessions' cleanups run. Never persisted, like
// SessionEpoch.
ActiveSessions int `gorm:"-"`
// SessionEpoch identifies a poll session generation; Connect bumps
// it. It complements ActiveSessions rather than duplicating it:
// the epoch is monotonic, which the HA prober needs to detect that
// a probe target reconnected mid-cycle — a refcount can return to
// its old value, a generation cannot. poll.go also uses the epoch
// returned by Connect as a "Connect ran" sentinel for its cleanup,
// and Disconnect logs it. Runtime-only.
SessionEpoch uint64 `gorm:"-"`
}
+1
View File
@@ -106,6 +106,7 @@ var _NodeCloneNeedsRegeneration = Node(struct {
DeletedAt *time.Time
IsOnline *bool
Unhealthy bool
ActiveSessions int
SessionEpoch uint64
}{})
+16 -4
View File
@@ -262,10 +262,21 @@ func (v NodeView) IsOnline() views.ValuePointer[bool] { return views.ValuePointe
// 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.
// ActiveSessions counts live poll sessions for this node.
// [State.Connect] increments it and every session release
// ([State.Disconnect]) decrements it, so the node goes offline
// exactly when its last session ends — regardless of the order in
// which overlapping sessions' cleanups run. Never persisted, like
// SessionEpoch.
func (v NodeView) ActiveSessions() int { return v.ж.ActiveSessions }
// SessionEpoch identifies a poll session generation; Connect bumps
// it. It complements ActiveSessions rather than duplicating it:
// the epoch is monotonic, which the HA prober needs to detect that
// a probe target reconnected mid-cycle — a refcount can return to
// its old value, a generation cannot. poll.go also uses the epoch
// returned by Connect as a "Connect ran" sentinel for its cleanup,
// and Disconnect logs it. Runtime-only.
func (v NodeView) SessionEpoch() uint64 { return v.ж.SessionEpoch }
func (v NodeView) String() string { return v.ж.String() }
@@ -295,6 +306,7 @@ var _NodeViewNeedsRegeneration = Node(struct {
DeletedAt *time.Time
IsOnline *bool
Unhealthy bool
ActiveSessions int
SessionEpoch uint64
}{})