43 lines
1,021 B
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()
|
|
}
|