mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-30 00:09:07 +01:00
[management] use peer.Status.LastSeen field to detect stale peer.Status.Connected values (#7268)
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/netbirdio/netbird/management/server/util"
|
||||
"github.com/netbirdio/netbird/shared/management/http/api"
|
||||
@@ -101,6 +102,32 @@ type PeerStatus struct { //nolint:revive
|
||||
RequiresApproval bool
|
||||
}
|
||||
|
||||
const (
|
||||
// HeartbeatInterval is how often the management instance serving a peer's sync
|
||||
// stream refreshes the peer's LastSeen.
|
||||
HeartbeatInterval = time.Minute
|
||||
// StaleAfter is how long a connected peer may go without a LastSeen refresh before
|
||||
// it reads as disconnected. It spans several heartbeats so one missed refresh does
|
||||
// not disconnect a live peer.
|
||||
StaleAfter = 5 * time.Minute
|
||||
)
|
||||
|
||||
// IsConnected reports whether a peer stored with the given connected flag and LastSeen
|
||||
// counts as connected. A management instance that stops without marking its peers
|
||||
// disconnected leaves the flag set, so a peer whose LastSeen is older than StaleAfter
|
||||
// reads as disconnected.
|
||||
func IsConnected(connected bool, lastSeen time.Time) bool {
|
||||
return connected && time.Since(lastSeen) < StaleAfter
|
||||
}
|
||||
|
||||
// AfterFind applies IsConnected to every peer loaded through gorm.
|
||||
func (p *Peer) AfterFind(*gorm.DB) error {
|
||||
if p.Status != nil {
|
||||
p.Status.Connected = IsConnected(p.Status.Connected, p.Status.LastSeen)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Location is a geo location information of a Peer based on public connection IP
|
||||
type Location struct {
|
||||
ConnectionIP net.IP `gorm:"serializer:json"` // from grpc peer or reverse proxy headers depends on setup
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -164,3 +165,22 @@ func TestPeerCapabilities(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsConnected(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
connected bool
|
||||
lastSeen time.Time
|
||||
want bool
|
||||
}{
|
||||
{name: "connected and recently seen", connected: true, lastSeen: time.Now().Add(-time.Minute), want: true},
|
||||
{name: "connected but not seen for longer than StaleAfter", connected: true, lastSeen: time.Now().Add(-StaleAfter - time.Minute)},
|
||||
{name: "connected but never seen", connected: true},
|
||||
{name: "disconnected and recently seen", lastSeen: time.Now()},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.want, IsConnected(tt.connected, tt.lastSeen))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user