evcc-io/plugin/aa55/pacer.go

43 lines
1,021 B
Go

package aa55
import (
"sync"
"time"
)
// pace spaces sends per inverter. Each source dials its own UDP connection, so
// the gap is enforced per remote address at package level, not per connection.
var pace = &pacer{gates: make(map[string]*inverterGate)}
type pacer struct {
mu sync.Mutex
gates map[string]*inverterGate
}
// inverterGate serializes exchanges to one inverter and tracks its last send.
type inverterGate struct {
mu sync.Mutex
last time.Time
}
// gate returns the shared gate for the inverter at addr, creating it on first use.
func (p *pacer) gate(addr string) *inverterGate {
p.mu.Lock()
defer p.mu.Unlock()
g := p.gates[addr]
if g == nil {
g = &inverterGate{}
p.gates[addr] = g
}
return g
}
// wait blocks until delay has elapsed since the previous send to this inverter,
// then records the new send time. The caller must hold g.mu.
func (g *inverterGate) wait(delay time.Duration) {
if d := time.Until(g.last.Add(delay)); d > 0 {
time.Sleep(d)
}
g.last = time.Now()
}