style: fix golangci-lint formatting issues
- Run gofmt on all swarm package files - Fix unnecessary int64 conversion in metrics.go - Break long line in leader_election.go for golines Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
050f99ef0c
commit
d17bc02493
11 changed files with 156 additions and 155 deletions
|
|
@ -209,13 +209,13 @@ func DefaultConfig() *Config {
|
||||||
BindAddr: "0.0.0.0",
|
BindAddr: "0.0.0.0",
|
||||||
BindPort: DefaultBindPort,
|
BindPort: DefaultBindPort,
|
||||||
Discovery: DiscoveryConfig{
|
Discovery: DiscoveryConfig{
|
||||||
JoinAddrs: nil,
|
JoinAddrs: nil,
|
||||||
GossipInterval: Duration{DefaultGossipInterval},
|
GossipInterval: Duration{DefaultGossipInterval},
|
||||||
PushPullInterval: Duration{DefaultPushPullInterval},
|
PushPullInterval: Duration{DefaultPushPullInterval},
|
||||||
NodeTimeout: Duration{DefaultNodeTimeout},
|
NodeTimeout: Duration{DefaultNodeTimeout},
|
||||||
DeadNodeTimeout: Duration{DefaultDeadNodeTimeout},
|
DeadNodeTimeout: Duration{DefaultDeadNodeTimeout},
|
||||||
AuthSecret: "",
|
AuthSecret: "",
|
||||||
RequireAuth: false,
|
RequireAuth: false,
|
||||||
EnableMessageSigning: false,
|
EnableMessageSigning: false,
|
||||||
},
|
},
|
||||||
Handoff: HandoffConfig{
|
Handoff: HandoffConfig{
|
||||||
|
|
@ -230,16 +230,16 @@ func DefaultConfig() *Config {
|
||||||
Timeout: Duration{10 * time.Second},
|
Timeout: Duration{10 * time.Second},
|
||||||
},
|
},
|
||||||
LoadMonitor: LoadMonitorConfig{
|
LoadMonitor: LoadMonitorConfig{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
Interval: Duration{DefaultLoadSampleInterval},
|
Interval: Duration{DefaultLoadSampleInterval},
|
||||||
SampleSize: DefaultLoadSampleSize,
|
SampleSize: DefaultLoadSampleSize,
|
||||||
CPUWeight: DefaultCPUWeight,
|
CPUWeight: DefaultCPUWeight,
|
||||||
MemoryWeight: DefaultMemoryWeight,
|
MemoryWeight: DefaultMemoryWeight,
|
||||||
SessionWeight: DefaultSessionWeight,
|
SessionWeight: DefaultSessionWeight,
|
||||||
OffloadThreshold: DefaultOffloadThreshold,
|
OffloadThreshold: DefaultOffloadThreshold,
|
||||||
MaxMemoryBytes: DefaultMaxMemoryBytes,
|
MaxMemoryBytes: DefaultMaxMemoryBytes,
|
||||||
MaxGoroutines: DefaultMaxGoroutines,
|
MaxGoroutines: DefaultMaxGoroutines,
|
||||||
MaxSessions: DefaultMaxSessions,
|
MaxSessions: DefaultMaxSessions,
|
||||||
},
|
},
|
||||||
LeaderElection: LeaderElectionConfig{
|
LeaderElection: LeaderElectionConfig{
|
||||||
Enabled: false,
|
Enabled: false,
|
||||||
|
|
@ -247,9 +247,9 @@ func DefaultConfig() *Config {
|
||||||
LeaderHeartbeatTimeout: Duration{10 * time.Second},
|
LeaderHeartbeatTimeout: Duration{10 * time.Second},
|
||||||
},
|
},
|
||||||
Metrics: MetricsConfig{
|
Metrics: MetricsConfig{
|
||||||
Enabled: false,
|
Enabled: false,
|
||||||
ExportInterval: Duration{10 * time.Second},
|
ExportInterval: Duration{10 * time.Second},
|
||||||
PrometheusEnabled: false,
|
PrometheusEnabled: false,
|
||||||
PrometheusEndpoint: "/metrics",
|
PrometheusEndpoint: "/metrics",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,10 +31,10 @@ type DiscoveryService struct {
|
||||||
rpcConn net.Listener
|
rpcConn net.Listener
|
||||||
auth *AuthProvider
|
auth *AuthProvider
|
||||||
|
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
running bool
|
running bool
|
||||||
stopChan chan struct{}
|
stopChan chan struct{}
|
||||||
once sync.Once
|
once sync.Once
|
||||||
|
|
||||||
// Sequence number for updates
|
// Sequence number for updates
|
||||||
seqNum uint64
|
seqNum uint64
|
||||||
|
|
@ -281,13 +281,13 @@ func (ds *DiscoveryService) gossipLoop() {
|
||||||
|
|
||||||
// GossipMessage represents a gossip message.
|
// GossipMessage represents a gossip message.
|
||||||
type GossipMessage struct {
|
type GossipMessage struct {
|
||||||
Type string `json:"type"` // "ping", "pong", "join", "update"
|
Type string `json:"type"` // "ping", "pong", "join", "update"
|
||||||
FromNode string `json:"from_node"`
|
FromNode string `json:"from_node"`
|
||||||
SeqNum uint64 `json:"seq_num"`
|
SeqNum uint64 `json:"seq_num"`
|
||||||
Timestamp int64 `json:"timestamp"`
|
Timestamp int64 `json:"timestamp"`
|
||||||
Payload []byte `json:"payload,omitempty"`
|
Payload []byte `json:"payload,omitempty"`
|
||||||
Nodes []*NodeInfo `json:"nodes,omitempty"` // For memberlist exchange
|
Nodes []*NodeInfo `json:"nodes,omitempty"` // For memberlist exchange
|
||||||
AuthToken *AuthToken `json:"auth_token,omitempty"`
|
AuthToken *AuthToken `json:"auth_token,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleGossip handles an incoming gossip message.
|
// handleGossip handles an incoming gossip message.
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,11 @@ import (
|
||||||
type HandoffReason string
|
type HandoffReason string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ReasonOverloaded HandoffReason = "overloaded" // Load is too high
|
ReasonOverloaded HandoffReason = "overloaded" // Load is too high
|
||||||
ReasonNoCapability HandoffReason = "no_capability" // Missing capability
|
ReasonNoCapability HandoffReason = "no_capability" // Missing capability
|
||||||
ReasonUserRequest HandoffReason = "user_request" // User explicitly requested
|
ReasonUserRequest HandoffReason = "user_request" // User explicitly requested
|
||||||
ReasonNodeLeave HandoffReason = "node_leave" // Node is leaving
|
ReasonNodeLeave HandoffReason = "node_leave" // Node is leaving
|
||||||
ReasonShutdown HandoffReason = "shutdown" // Graceful shutdown
|
ReasonShutdown HandoffReason = "shutdown" // Graceful shutdown
|
||||||
)
|
)
|
||||||
|
|
||||||
// HandoffState represents the state of a handoff operation.
|
// HandoffState represents the state of a handoff operation.
|
||||||
|
|
@ -42,27 +42,27 @@ const (
|
||||||
|
|
||||||
// HandoffRequest represents a request to hand off a session.
|
// HandoffRequest represents a request to hand off a session.
|
||||||
type HandoffRequest struct {
|
type HandoffRequest struct {
|
||||||
RequestID string `json:"request_id"`
|
RequestID string `json:"request_id"`
|
||||||
Reason HandoffReason `json:"reason"`
|
Reason HandoffReason `json:"reason"`
|
||||||
SessionKey string `json:"session_key"`
|
SessionKey string `json:"session_key"`
|
||||||
SessionMessages []SessionMessage `json:"session_messages,omitempty"`
|
SessionMessages []SessionMessage `json:"session_messages,omitempty"`
|
||||||
Context map[string]any `json:"context,omitempty"`
|
Context map[string]any `json:"context,omitempty"`
|
||||||
RequiredCap string `json:"required_cap,omitempty"`
|
RequiredCap string `json:"required_cap,omitempty"`
|
||||||
Metadata map[string]string `json:"metadata,omitempty"`
|
Metadata map[string]string `json:"metadata,omitempty"`
|
||||||
FromNodeID string `json:"from_node_id"`
|
FromNodeID string `json:"from_node_id"`
|
||||||
FromNodeAddr string `json:"from_node_addr"`
|
FromNodeAddr string `json:"from_node_addr"`
|
||||||
Timestamp int64 `json:"timestamp"`
|
Timestamp int64 `json:"timestamp"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandoffResponse represents the response to a handoff request.
|
// HandoffResponse represents the response to a handoff request.
|
||||||
type HandoffResponse struct {
|
type HandoffResponse struct {
|
||||||
RequestID string `json:"request_id"`
|
RequestID string `json:"request_id"`
|
||||||
Accepted bool `json:"accepted"`
|
Accepted bool `json:"accepted"`
|
||||||
NodeID string `json:"node_id"`
|
NodeID string `json:"node_id"`
|
||||||
Reason string `json:"reason,omitempty"`
|
Reason string `json:"reason,omitempty"`
|
||||||
SessionKey string `json:"session_key,omitempty"` // New session key on target
|
SessionKey string `json:"session_key,omitempty"` // New session key on target
|
||||||
Timestamp int64 `json:"timestamp"`
|
Timestamp int64 `json:"timestamp"`
|
||||||
State HandoffState `json:"state"`
|
State HandoffState `json:"state"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandoffCoordinator coordinates handoff operations between nodes.
|
// HandoffCoordinator coordinates handoff operations between nodes.
|
||||||
|
|
@ -71,9 +71,9 @@ type HandoffCoordinator struct {
|
||||||
membership *MembershipManager
|
membership *MembershipManager
|
||||||
config HandoffConfig
|
config HandoffConfig
|
||||||
|
|
||||||
pending map[string]*HandoffOperation // request_id -> operation
|
pending map[string]*HandoffOperation // request_id -> operation
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
conn *net.UDPConn
|
conn *net.UDPConn
|
||||||
|
|
||||||
// Accept/reject callbacks
|
// Accept/reject callbacks
|
||||||
onHandoffRequest func(*HandoffRequest) *HandoffResponse
|
onHandoffRequest func(*HandoffRequest) *HandoffResponse
|
||||||
|
|
@ -82,22 +82,22 @@ type HandoffCoordinator struct {
|
||||||
|
|
||||||
// HandoffOperation represents an ongoing handoff operation.
|
// HandoffOperation represents an ongoing handoff operation.
|
||||||
type HandoffOperation struct {
|
type HandoffOperation struct {
|
||||||
Request *HandoffRequest
|
Request *HandoffRequest
|
||||||
Response *HandoffResponse
|
Response *HandoffResponse
|
||||||
State HandoffState
|
State HandoffState
|
||||||
StartTime time.Time
|
StartTime time.Time
|
||||||
LastUpdate time.Time
|
LastUpdate time.Time
|
||||||
RetryCount int
|
RetryCount int
|
||||||
TargetNode *NodeWithState
|
TargetNode *NodeWithState
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHandoffCoordinator creates a new handoff coordinator.
|
// NewHandoffCoordinator creates a new handoff coordinator.
|
||||||
func NewHandoffCoordinator(ds *DiscoveryService, config HandoffConfig) (*HandoffCoordinator, error) {
|
func NewHandoffCoordinator(ds *DiscoveryService, config HandoffConfig) (*HandoffCoordinator, error) {
|
||||||
hc := &HandoffCoordinator{
|
hc := &HandoffCoordinator{
|
||||||
discovery: ds,
|
discovery: ds,
|
||||||
membership: ds.membership,
|
membership: ds.membership,
|
||||||
config: config,
|
config: config,
|
||||||
pending: make(map[string]*HandoffOperation),
|
pending: make(map[string]*HandoffOperation),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind UDP socket for handoff messages
|
// Bind UDP socket for handoff messages
|
||||||
|
|
|
||||||
|
|
@ -178,7 +178,8 @@ func (le *LeaderElection) monitorLeader() {
|
||||||
|
|
||||||
// Check if leader is still in the membership
|
// Check if leader is still in the membership
|
||||||
if _, exists := le.membership.GetNode(leaderID); !exists {
|
if _, exists := le.membership.GetNode(leaderID); !exists {
|
||||||
logger.WarnCF("swarm", "Leader no longer in membership, triggering reelection", map[string]any{"leader_id": leaderID})
|
logger.WarnCF("swarm", "Leader no longer in membership, triggering reelection",
|
||||||
|
map[string]any{"leader_id": leaderID})
|
||||||
// Trigger reelection by clearing current leader
|
// Trigger reelection by clearing current leader
|
||||||
le.mu.Lock()
|
le.mu.Lock()
|
||||||
le.currentLeader = ""
|
le.currentLeader = ""
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@ import (
|
||||||
|
|
||||||
// LoadMonitor monitors system load and calculates a load score.
|
// LoadMonitor monitors system load and calculates a load score.
|
||||||
type LoadMonitor struct {
|
type LoadMonitor struct {
|
||||||
config *LoadMonitorConfig
|
config *LoadMonitorConfig
|
||||||
samples []float64
|
samples []float64
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
sessionCount int
|
sessionCount int
|
||||||
ticker *time.Ticker
|
ticker *time.Ticker
|
||||||
stopChan chan struct{}
|
stopChan chan struct{}
|
||||||
|
|
@ -33,9 +33,9 @@ func NewLoadMonitor(config *LoadMonitorConfig) *LoadMonitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
lm := &LoadMonitor{
|
lm := &LoadMonitor{
|
||||||
config: config,
|
config: config,
|
||||||
samples: make([]float64, 0, config.SampleSize),
|
samples: make([]float64, 0, config.SampleSize),
|
||||||
stopChan: make(chan struct{}),
|
stopChan: make(chan struct{}),
|
||||||
onThreshold: make([]func(float64), 0),
|
onThreshold: make([]func(float64), 0),
|
||||||
}
|
}
|
||||||
return lm
|
return lm
|
||||||
|
|
@ -89,20 +89,20 @@ func (lm *LoadMonitor) run() {
|
||||||
|
|
||||||
// LoadMetrics represents current load metrics.
|
// LoadMetrics represents current load metrics.
|
||||||
type LoadMetrics struct {
|
type LoadMetrics struct {
|
||||||
CPUUsage float64 `json:"cpu_usage"`
|
CPUUsage float64 `json:"cpu_usage"`
|
||||||
MemoryUsage float64 `json:"memory_usage"`
|
MemoryUsage float64 `json:"memory_usage"`
|
||||||
ActiveSessions int `json:"active_sessions"`
|
ActiveSessions int `json:"active_sessions"`
|
||||||
Goroutines int `json:"goroutines"`
|
Goroutines int `json:"goroutines"`
|
||||||
Score float64 `json:"score"`
|
Score float64 `json:"score"`
|
||||||
Timestamp int64 `json:"timestamp"`
|
Timestamp int64 `json:"timestamp"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCurrentLoad returns the current load metrics.
|
// GetCurrentLoad returns the current load metrics.
|
||||||
func (lm *LoadMonitor) GetCurrentLoad() *LoadMetrics {
|
func (lm *LoadMonitor) GetCurrentLoad() *LoadMetrics {
|
||||||
metrics := &LoadMetrics{
|
metrics := &LoadMetrics{
|
||||||
ActiveSessions: lm.GetSessionCount(),
|
ActiveSessions: lm.GetSessionCount(),
|
||||||
Goroutines: runtime.NumGoroutine(),
|
Goroutines: runtime.NumGoroutine(),
|
||||||
Timestamp: time.Now().UnixNano(),
|
Timestamp: time.Now().UnixNano(),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get memory usage
|
// Get memory usage
|
||||||
|
|
@ -245,7 +245,7 @@ func (lm *LoadMonitor) GetTrend() string {
|
||||||
|
|
||||||
// Simple linear regression to detect trend
|
// Simple linear regression to detect trend
|
||||||
n := float64(len(lm.samples))
|
n := float64(len(lm.samples))
|
||||||
sumX := n*(n-1)/2
|
sumX := n * (n - 1) / 2
|
||||||
sumY := 0.0
|
sumY := 0.0
|
||||||
sumXY := 0.0
|
sumXY := 0.0
|
||||||
|
|
||||||
|
|
@ -255,7 +255,7 @@ func (lm *LoadMonitor) GetTrend() string {
|
||||||
sumXY += x * s
|
sumXY += x * s
|
||||||
}
|
}
|
||||||
|
|
||||||
slope := (n*sumXY - sumX*sumY) / (n*(n-1)*(2*n-1)/6)
|
slope := (n*sumXY - sumX*sumY) / (n * (n - 1) * (2*n - 1) / 6)
|
||||||
|
|
||||||
if slope > TrendIncreasingThreshold {
|
if slope > TrendIncreasingThreshold {
|
||||||
return "increasing"
|
return "increasing"
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,9 @@ type MembershipManager struct {
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
|
|
||||||
// Event callbacks
|
// Event callbacks
|
||||||
onJoin []func(*NodeInfo)
|
onJoin []func(*NodeInfo)
|
||||||
onLeave []func(*NodeInfo)
|
onLeave []func(*NodeInfo)
|
||||||
onUpdate []func(*NodeInfo)
|
onUpdate []func(*NodeInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMembershipManager creates a new membership manager.
|
// NewMembershipManager creates a new membership manager.
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,13 @@ type MetricsCollector struct {
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
|
|
||||||
// Counters (atomic for performance)
|
// Counters (atomic for performance)
|
||||||
messagesSent atomic.Int64
|
messagesSent atomic.Int64
|
||||||
messagesReceived atomic.Int64
|
messagesReceived atomic.Int64
|
||||||
handoffsInitiated atomic.Int64
|
handoffsInitiated atomic.Int64
|
||||||
handoffsAccepted atomic.Int64
|
handoffsAccepted atomic.Int64
|
||||||
handoffsRejected atomic.Int64
|
handoffsRejected atomic.Int64
|
||||||
handoffsFailed atomic.Int64
|
handoffsFailed atomic.Int64
|
||||||
electionsWon atomic.Int64
|
electionsWon atomic.Int64
|
||||||
|
|
||||||
// Gauges (use atomic.Value for float64)
|
// Gauges (use atomic.Value for float64)
|
||||||
currentLoadScore atomic.Value // float64
|
currentLoadScore atomic.Value // float64
|
||||||
|
|
@ -40,9 +40,9 @@ type MetricsCollector struct {
|
||||||
|
|
||||||
// LatencyBucket tracks latency distribution.
|
// LatencyBucket tracks latency distribution.
|
||||||
type LatencyBucket struct {
|
type LatencyBucket struct {
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
count int64
|
count int64
|
||||||
sum int64
|
sum int64
|
||||||
buckets [12]int64 // 0-1ms, 1-2ms, 2-5ms, 5-10ms, 10-20ms, 20-50ms, 50-100ms, 100-200ms, 200-500ms, 500ms-1s, 1-2s, 2s+
|
buckets [12]int64 // 0-1ms, 1-2ms, 2-5ms, 5-10ms, 10-20ms, 20-50ms, 50-100ms, 100-200ms, 200-500ms, 500ms-1s, 1-2s, 2s+
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -118,7 +118,7 @@ func (m *MetricsCollector) RecordLatency(operation string, latency time.Duration
|
||||||
bucket := m.latencyBuckets[operation]
|
bucket := m.latencyBuckets[operation]
|
||||||
m.mu.Unlock()
|
m.mu.Unlock()
|
||||||
|
|
||||||
ms := int64(latency.Milliseconds())
|
ms := latency.Milliseconds()
|
||||||
|
|
||||||
bucket.mu.Lock()
|
bucket.mu.Lock()
|
||||||
bucket.count++
|
bucket.count++
|
||||||
|
|
@ -174,24 +174,24 @@ func (m *MetricsCollector) GetMetrics() map[string]any {
|
||||||
|
|
||||||
return map[string]any{
|
return map[string]any{
|
||||||
// Counters
|
// Counters
|
||||||
"messages_sent": m.messagesSent.Load(),
|
"messages_sent": m.messagesSent.Load(),
|
||||||
"messages_received": m.messagesReceived.Load(),
|
"messages_received": m.messagesReceived.Load(),
|
||||||
"handoffs_initiated": m.handoffsInitiated.Load(),
|
"handoffs_initiated": m.handoffsInitiated.Load(),
|
||||||
"handoffs_accepted": m.handoffsAccepted.Load(),
|
"handoffs_accepted": m.handoffsAccepted.Load(),
|
||||||
"handoffs_rejected": m.handoffsRejected.Load(),
|
"handoffs_rejected": m.handoffsRejected.Load(),
|
||||||
"handoffs_failed": m.handoffsFailed.Load(),
|
"handoffs_failed": m.handoffsFailed.Load(),
|
||||||
"elections_won": m.electionsWon.Load(),
|
"elections_won": m.electionsWon.Load(),
|
||||||
|
|
||||||
// Gauges
|
// Gauges
|
||||||
"load_score": m.currentLoadScore.Load(),
|
"load_score": m.currentLoadScore.Load(),
|
||||||
"active_sessions": m.activeSessions.Load(),
|
"active_sessions": m.activeSessions.Load(),
|
||||||
"member_count": m.memberCount.Load(),
|
"member_count": m.memberCount.Load(),
|
||||||
|
|
||||||
// System info
|
// System info
|
||||||
"uptime_seconds": time.Since(m.startTime).Seconds(),
|
"uptime_seconds": time.Since(m.startTime).Seconds(),
|
||||||
|
|
||||||
// Latency histograms
|
// Latency histograms
|
||||||
"latency_ms": latency,
|
"latency_ms": latency,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -205,7 +205,7 @@ func (m *MetricsCollector) percentile(bucket *LatencyBucket, p float64) float64
|
||||||
cumulative := int64(0)
|
cumulative := int64(0)
|
||||||
|
|
||||||
// Upper bounds for each bucket in ms
|
// Upper bounds for each bucket in ms
|
||||||
upperBounds := []int64{1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 1<<62}
|
upperBounds := []int64{1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 1 << 62}
|
||||||
|
|
||||||
for i, count := range bucket.buckets {
|
for i, count := range bucket.buckets {
|
||||||
cumulative += count
|
cumulative += count
|
||||||
|
|
|
||||||
|
|
@ -63,13 +63,13 @@ const (
|
||||||
|
|
||||||
// NodeState represents the state of a node in the membership view.
|
// NodeState represents the state of a node in the membership view.
|
||||||
type NodeState struct {
|
type NodeState struct {
|
||||||
Node *NodeInfo `json:"node"`
|
Node *NodeInfo `json:"node"`
|
||||||
Status NodeStatus `json:"status"`
|
Status NodeStatus `json:"status"`
|
||||||
StatusSince int64 `json:"status_since"` // Unix nano when status was set
|
StatusSince int64 `json:"status_since"` // Unix nano when status was set
|
||||||
LastSeen int64 `json:"last_seen"` // Unix nano of last sighting
|
LastSeen int64 `json:"last_seen"` // Unix nano of last sighting
|
||||||
LastPing int64 `json:"last_ping"` // Unix nano of last successful ping
|
LastPing int64 `json:"last_ping"` // Unix nano of last successful ping
|
||||||
PingSuccess int `json:"ping_success"` // Consecutive successful pings
|
PingSuccess int `json:"ping_success"` // Consecutive successful pings
|
||||||
PingFailure int `json:"ping_failure"` // Consecutive failed pings
|
PingFailure int `json:"ping_failure"` // Consecutive failed pings
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsAvailable returns true if the node is available for handoff.
|
// IsAvailable returns true if the node is available for handoff.
|
||||||
|
|
@ -85,9 +85,9 @@ func (ns *NodeState) UpdateStatus(status NodeStatus) {
|
||||||
|
|
||||||
// NodeEvent represents a node state change event.
|
// NodeEvent represents a node state change event.
|
||||||
type NodeEvent struct {
|
type NodeEvent struct {
|
||||||
Node *NodeInfo `json:"node"`
|
Node *NodeInfo `json:"node"`
|
||||||
Event EventType `json:"event"`
|
Event EventType `json:"event"`
|
||||||
Time int64 `json:"time"`
|
Time int64 `json:"time"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// EventType represents the type of node event.
|
// EventType represents the type of node event.
|
||||||
|
|
@ -195,13 +195,13 @@ func (ed *EventDispatcher) DispatchContext(event *NodeEvent, ctx context.Context
|
||||||
|
|
||||||
// NodeStats tracks statistics about a node.
|
// NodeStats tracks statistics about a node.
|
||||||
type NodeStats struct {
|
type NodeStats struct {
|
||||||
MessagesSent int64 `json:"messages_sent"`
|
MessagesSent int64 `json:"messages_sent"`
|
||||||
MessagesReceived int64 `json:"messages_received"`
|
MessagesReceived int64 `json:"messages_received"`
|
||||||
HandoffsAccepted int `json:"handoffs_accepted"`
|
HandoffsAccepted int `json:"handoffs_accepted"`
|
||||||
HandoffsInitiated int `json:"handoffs_initiated"`
|
HandoffsInitiated int `json:"handoffs_initiated"`
|
||||||
LastError string `json:"last_error,omitempty"`
|
LastError string `json:"last_error,omitempty"`
|
||||||
LastErrorTime time.Time `json:"last_error_time,omitempty"`
|
LastErrorTime time.Time `json:"last_error_time,omitempty"`
|
||||||
UptimeStart time.Time `json:"uptime_start"`
|
UptimeStart time.Time `json:"uptime_start"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeWithState combines a node with its state and stats.
|
// NodeWithState combines a node with its state and stats.
|
||||||
|
|
@ -222,9 +222,9 @@ func (nws *NodeWithState) IsAvailable() bool {
|
||||||
// ClusterView represents the current view of the cluster.
|
// ClusterView represents the current view of the cluster.
|
||||||
type ClusterView struct {
|
type ClusterView struct {
|
||||||
Nodes map[string]*NodeWithState `json:"nodes"`
|
Nodes map[string]*NodeWithState `json:"nodes"`
|
||||||
LocalNodeID string `json:"local_node_id"`
|
LocalNodeID string `json:"local_node_id"`
|
||||||
Size int `json:"size"`
|
Size int `json:"size"`
|
||||||
Version int64 `json:"version"` // View version for conflict detection
|
Version int64 `json:"version"` // View version for conflict detection
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,12 @@ import (
|
||||||
|
|
||||||
// SessionTransfer handles session migration between nodes.
|
// SessionTransfer handles session migration between nodes.
|
||||||
type SessionTransfer struct {
|
type SessionTransfer struct {
|
||||||
config RPCConfig
|
config RPCConfig
|
||||||
localNode *NodeInfo
|
localNode *NodeInfo
|
||||||
transfers map[string]*TransferOperation // session_key -> operation
|
transfers map[string]*TransferOperation // session_key -> operation
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
conn *net.UDPConn
|
conn *net.UDPConn
|
||||||
onReceive func(*TransferPayload)
|
onReceive func(*TransferPayload)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TransferOperation represents an ongoing transfer operation.
|
// TransferOperation represents an ongoing transfer operation.
|
||||||
|
|
@ -49,15 +49,15 @@ const (
|
||||||
|
|
||||||
// TransferPayload represents the session data being transferred.
|
// TransferPayload represents the session data being transferred.
|
||||||
type TransferPayload struct {
|
type TransferPayload struct {
|
||||||
SessionKey string `json:"session_key"`
|
SessionKey string `json:"session_key"`
|
||||||
SourceNodeID string `json:"source_node_id"`
|
SourceNodeID string `json:"source_node_id"`
|
||||||
TargetNodeID string `json:"target_node_id"`
|
TargetNodeID string `json:"target_node_id"`
|
||||||
Messages []SessionMessage `json:"messages"`
|
Messages []SessionMessage `json:"messages"`
|
||||||
Summary string `json:"summary,omitempty"`
|
Summary string `json:"summary,omitempty"`
|
||||||
Context map[string]any `json:"context,omitempty"`
|
Context map[string]any `json:"context,omitempty"`
|
||||||
Metadata map[string]string `json:"metadata,omitempty"`
|
Metadata map[string]string `json:"metadata,omitempty"`
|
||||||
Timestamp int64 `json:"timestamp"`
|
Timestamp int64 `json:"timestamp"`
|
||||||
TransferID string `json:"transfer_id"`
|
TransferID string `json:"transfer_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSessionTransfer creates a new session transfer handler.
|
// NewSessionTransfer creates a new session transfer handler.
|
||||||
|
|
|
||||||
|
|
@ -85,11 +85,11 @@ func TestClusterView(t *testing.T) {
|
||||||
|
|
||||||
func TestLoadMonitor(t *testing.T) {
|
func TestLoadMonitor(t *testing.T) {
|
||||||
config := &LoadMonitorConfig{
|
config := &LoadMonitorConfig{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
Interval: Duration{time.Second},
|
Interval: Duration{time.Second},
|
||||||
SampleSize: 10,
|
SampleSize: 10,
|
||||||
CPUWeight: 0.3,
|
CPUWeight: 0.3,
|
||||||
MemoryWeight: 0.3,
|
MemoryWeight: 0.3,
|
||||||
SessionWeight: 0.4,
|
SessionWeight: 0.4,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,17 +9,17 @@ package swarm
|
||||||
// SessionMessage represents a message in a session.
|
// SessionMessage represents a message in a session.
|
||||||
// This is shared across handoff and session transfer.
|
// This is shared across handoff and session transfer.
|
||||||
type SessionMessage struct {
|
type SessionMessage struct {
|
||||||
Role string `json:"role"`
|
Role string `json:"role"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
Timestamp int64 `json:"timestamp,omitempty"`
|
Timestamp int64 `json:"timestamp,omitempty"`
|
||||||
ToolCalls []ToolCallData `json:"tool_calls,omitempty"`
|
ToolCalls []ToolCallData `json:"tool_calls,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToolCallData represents tool call information in a message.
|
// ToolCallData represents tool call information in a message.
|
||||||
type ToolCallData struct {
|
type ToolCallData struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Arguments map[string]any `json:"arguments"`
|
Arguments map[string]any `json:"arguments"`
|
||||||
Result string `json:"result,omitempty"`
|
Result string `json:"result,omitempty"`
|
||||||
Extra map[string]any `json:"extra,omitempty"`
|
Extra map[string]any `json:"extra,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue