Files
go-alived/internal/vrrp/priority.go
loveuer 94c1c81ee0 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]
2026-03-04 00:14:47 -08:00

100 lines
2.7 KiB
Go

package vrrp
import (
"sync"
"time"
)
// PriorityCalculator manages VRRP priority with support for dynamic adjustment.
type PriorityCalculator struct {
basePriority uint8
currentPriority uint8
mu sync.RWMutex
}
// NewPriorityCalculator creates a new PriorityCalculator with the specified base priority.
func NewPriorityCalculator(basePriority uint8) *PriorityCalculator {
return &PriorityCalculator{
basePriority: basePriority,
currentPriority: basePriority,
}
}
// GetPriority returns the current priority.
func (pc *PriorityCalculator) GetPriority() uint8 {
pc.mu.RLock()
defer pc.mu.RUnlock()
return pc.currentPriority
}
// DecreasePriority decreases the current priority by the specified amount.
// The priority will not go below 0.
func (pc *PriorityCalculator) DecreasePriority(amount uint8) {
pc.mu.Lock()
defer pc.mu.Unlock()
if pc.currentPriority > amount {
pc.currentPriority -= amount
} else {
pc.currentPriority = 0
}
}
// IncreasePriority increases the current priority by the specified amount.
// The priority will not exceed 255 or the base priority.
func (pc *PriorityCalculator) IncreasePriority(amount uint8) {
pc.mu.Lock()
defer pc.mu.Unlock()
newPriority := pc.currentPriority + amount
if newPriority > pc.basePriority {
newPriority = pc.basePriority
}
if newPriority < pc.currentPriority { // overflow check
newPriority = pc.basePriority
}
pc.currentPriority = newPriority
}
// ResetPriority resets the priority to the base value.
func (pc *PriorityCalculator) ResetPriority() {
pc.mu.Lock()
defer pc.mu.Unlock()
pc.currentPriority = pc.basePriority
}
// SetBasePriority sets a new base priority and resets current priority to match.
func (pc *PriorityCalculator) SetBasePriority(priority uint8) {
pc.mu.Lock()
defer pc.mu.Unlock()
pc.basePriority = priority
pc.currentPriority = priority
}
// ShouldBecomeMaster determines if the local node should become master
// based on priority comparison and IP address tie-breaking.
func ShouldBecomeMaster(localPriority, remotePriority uint8, localIP, remoteIP string) bool {
if localPriority > remotePriority {
return true
}
if localPriority == remotePriority {
return localIP > remoteIP
}
return false
}
// CalculateMasterDownInterval calculates the master down interval
// according to VRRP specification: (3 * Advertisement_Interval).
func CalculateMasterDownInterval(advertInt uint8) time.Duration {
return time.Duration(3*int(advertInt)) * time.Second
}
// CalculateSkewTime calculates the skew time for master down timer
// according to VRRP specification: ((256 - Priority) / 256).
func CalculateSkewTime(priority uint8) time.Duration {
skew := float64(256-int(priority)) / 256.0
return time.Duration(skew * float64(time.Second))
}