fix: resolve critical bugs and refactor code structure
P0 Fixes: - Fix potential panic in factory.go due to unsafe type assertion - Fix VIP CIDR mask being lost during parsing (was hardcoded to /32) P1 Fixes: - Fix go.mod incorrect indirect dependency markers - Fix receiveLoop blocking issue preventing graceful shutdown Refactoring: - Split state.go into state.go, timer.go, priority.go, history.go - Split monitor.go into monitor.go and manager.go - Add IncreasePriority() method for complete priority adjustment - Fix go vet format string warning in test.go 🤖 Generated with [Qoder][https://qoder.com]
This commit is contained in:
95
internal/vrrp/history.go
Normal file
95
internal/vrrp/history.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package vrrp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// StateTransition represents a single state transition event.
|
||||
type StateTransition struct {
|
||||
From State
|
||||
To State
|
||||
Timestamp time.Time
|
||||
Reason string
|
||||
}
|
||||
|
||||
// StateHistory maintains a bounded history of state transitions.
|
||||
type StateHistory struct {
|
||||
transitions []StateTransition
|
||||
maxSize int
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
// NewStateHistory creates a new StateHistory with the specified maximum size.
|
||||
func NewStateHistory(maxSize int) *StateHistory {
|
||||
return &StateHistory{
|
||||
transitions: make([]StateTransition, 0, maxSize),
|
||||
maxSize: maxSize,
|
||||
}
|
||||
}
|
||||
|
||||
// Add records a new state transition.
|
||||
func (sh *StateHistory) Add(from, to State, reason string) {
|
||||
sh.mu.Lock()
|
||||
defer sh.mu.Unlock()
|
||||
|
||||
transition := StateTransition{
|
||||
From: from,
|
||||
To: to,
|
||||
Timestamp: time.Now(),
|
||||
Reason: reason,
|
||||
}
|
||||
|
||||
sh.transitions = append(sh.transitions, transition)
|
||||
|
||||
// Maintain bounded size using ring buffer style
|
||||
if len(sh.transitions) > sh.maxSize {
|
||||
// Copy to new slice to allow garbage collection of old backing array
|
||||
newTransitions := make([]StateTransition, len(sh.transitions)-1, sh.maxSize)
|
||||
copy(newTransitions, sh.transitions[1:])
|
||||
sh.transitions = newTransitions
|
||||
}
|
||||
}
|
||||
|
||||
// GetRecent returns the most recent n transitions.
|
||||
func (sh *StateHistory) GetRecent(n int) []StateTransition {
|
||||
sh.mu.RLock()
|
||||
defer sh.mu.RUnlock()
|
||||
|
||||
if n > len(sh.transitions) {
|
||||
n = len(sh.transitions)
|
||||
}
|
||||
|
||||
start := len(sh.transitions) - n
|
||||
result := make([]StateTransition, n)
|
||||
copy(result, sh.transitions[start:])
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Len returns the number of recorded transitions.
|
||||
func (sh *StateHistory) Len() int {
|
||||
sh.mu.RLock()
|
||||
defer sh.mu.RUnlock()
|
||||
return len(sh.transitions)
|
||||
}
|
||||
|
||||
// String returns a formatted string representation of the history.
|
||||
func (sh *StateHistory) String() string {
|
||||
sh.mu.RLock()
|
||||
defer sh.mu.RUnlock()
|
||||
|
||||
if len(sh.transitions) == 0 {
|
||||
return "No state transitions"
|
||||
}
|
||||
|
||||
result := "State transition history:\n"
|
||||
for _, t := range sh.transitions {
|
||||
result += fmt.Sprintf(" %s: %s -> %s (%s)\n",
|
||||
t.Timestamp.Format("2006-01-02 15:04:05"),
|
||||
t.From, t.To, t.Reason)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user