simplify code and fix metrics response

This commit is contained in:
yusing 2025-02-14 02:19:58 +08:00
parent f84bd6a1e8
commit 409048c206
3 changed files with 28 additions and 59 deletions

View file

@ -31,7 +31,7 @@ func (p *Poller[T, AggregateT]) ServeHTTP(w http.ResponseWriter, r *http.Request
minInterval := 1 * time.Second minInterval := 1 * time.Second
if interval == 0 { if interval == 0 {
interval = p.interval() interval = pollInterval
} }
if interval < minInterval { if interval < minInterval {
interval = minInterval interval = minInterval
@ -66,11 +66,10 @@ func (p *Poller[T, AggregateT]) getRespData(r *http.Request) (any, error) {
if period == "" { if period == "" {
return p.GetLastResult(), nil return p.GetLastResult(), nil
} }
periodFilter := Filter(period) rangeData, ok := p.Get(Filter(period))
if !periodFilter.IsValid() { if !ok {
return nil, errors.New("invalid period") return nil, errors.New("invalid period")
} }
rangeData := p.Get(periodFilter)
if p.aggregator != nil { if p.aggregator != nil {
total, aggregated := p.aggregator(rangeData, query) total, aggregated := p.aggregator(rangeData, query)
return map[string]any{ return map[string]any{

View file

@ -6,31 +6,21 @@ import (
) )
type Period[T any] struct { type Period[T any] struct {
FiveMinutes *Entries[T] Entries map[Filter]*Entries[T]
FifteenMinutes *Entries[T] mu sync.RWMutex
OneHour *Entries[T]
OneDay *Entries[T]
OneMonth *Entries[T]
mu sync.RWMutex
} }
type Filter string type Filter string
const (
PeriodFiveMinutes Filter = "5m"
PeriodFifteenMinutes Filter = "15m"
PeriodOneHour Filter = "1h"
PeriodOneDay Filter = "1d"
PeriodOneMonth Filter = "1mo"
)
func NewPeriod[T any]() *Period[T] { func NewPeriod[T any]() *Period[T] {
return &Period[T]{ return &Period[T]{
FiveMinutes: newEntries[T](5 * time.Minute), Entries: map[Filter]*Entries[T]{
FifteenMinutes: newEntries[T](15 * time.Minute), "5m": newEntries[T](5 * time.Minute),
OneHour: newEntries[T](1 * time.Hour), "15m": newEntries[T](15 * time.Minute),
OneDay: newEntries[T](24 * time.Hour), "1h": newEntries[T](1 * time.Hour),
OneMonth: newEntries[T](30 * 24 * time.Hour), "1d": newEntries[T](24 * time.Hour),
"1mo": newEntries[T](30 * 24 * time.Hour),
},
} }
} }
@ -38,36 +28,17 @@ func (p *Period[T]) Add(info *T) {
p.mu.Lock() p.mu.Lock()
defer p.mu.Unlock() defer p.mu.Unlock()
now := time.Now() now := time.Now()
p.FiveMinutes.Add(now, info) for _, period := range p.Entries {
p.FifteenMinutes.Add(now, info) period.Add(now, info)
p.OneHour.Add(now, info) }
p.OneDay.Add(now, info)
p.OneMonth.Add(now, info)
} }
func (p *Period[T]) Get(filter Filter) []*T { func (p *Period[T]) Get(filter Filter) ([]*T, bool) {
p.mu.RLock() p.mu.RLock()
defer p.mu.RUnlock() defer p.mu.RUnlock()
switch filter { period, ok := p.Entries[filter]
case PeriodFiveMinutes: if !ok {
return p.FiveMinutes.Get() return nil, false
case PeriodFifteenMinutes:
return p.FifteenMinutes.Get()
case PeriodOneHour:
return p.OneHour.Get()
case PeriodOneDay:
return p.OneDay.Get()
case PeriodOneMonth:
return p.OneMonth.Get()
default:
panic("invalid period filter")
} }
} return period.Get(), true
func (filter Filter) IsValid() bool {
switch filter {
case PeriodFiveMinutes, PeriodFifteenMinutes, PeriodOneHour, PeriodOneDay, PeriodOneMonth:
return true
}
return false
} }

View file

@ -30,7 +30,10 @@ type (
} }
) )
const gatherErrsInterval = 30 * time.Second const (
pollInterval = 1 * time.Second
gatherErrsInterval = 30 * time.Second
)
func NewPoller[T any]( func NewPoller[T any](
name string, name string,
@ -61,10 +64,6 @@ func (p *Poller[T, AggregateT]) WithResultFilter(filter FilterFunc[T]) *Poller[T
return p return p
} }
func (p *Poller[T, AggregateT]) interval() time.Duration {
return p.period.FiveMinutes.interval
}
func (p *Poller[T, AggregateT]) appendErr(err error) { func (p *Poller[T, AggregateT]) appendErr(err error) {
if len(p.errs) == 0 { if len(p.errs) == 0 {
p.errs = []pollErr{ p.errs = []pollErr{
@ -97,7 +96,7 @@ func (p *Poller[T, AggregateT]) clearErrs() {
} }
func (p *Poller[T, AggregateT]) pollWithTimeout(ctx context.Context) { func (p *Poller[T, AggregateT]) pollWithTimeout(ctx context.Context) {
ctx, cancel := context.WithTimeout(ctx, p.interval()) ctx, cancel := context.WithTimeout(ctx, pollInterval)
defer cancel() defer cancel()
data, err := p.poll(ctx, p.lastResult) data, err := p.poll(ctx, p.lastResult)
if err != nil { if err != nil {
@ -111,12 +110,12 @@ func (p *Poller[T, AggregateT]) pollWithTimeout(ctx context.Context) {
func (p *Poller[T, AggregateT]) Start() { func (p *Poller[T, AggregateT]) Start() {
go func() { go func() {
ctx := task.RootContext() ctx := task.RootContext()
ticker := time.NewTicker(p.interval()) ticker := time.NewTicker(pollInterval)
gatherErrsTicker := time.NewTicker(gatherErrsInterval) gatherErrsTicker := time.NewTicker(gatherErrsInterval)
defer ticker.Stop() defer ticker.Stop()
defer gatherErrsTicker.Stop() defer gatherErrsTicker.Stop()
logging.Debug().Msgf("Starting poller %s with interval %s", p.name, p.interval()) logging.Debug().Msgf("Starting poller %s with interval %s", p.name, pollInterval)
p.pollWithTimeout(ctx) p.pollWithTimeout(ctx)
@ -137,7 +136,7 @@ func (p *Poller[T, AggregateT]) Start() {
}() }()
} }
func (p *Poller[T, AggregateT]) Get(filter Filter) []*T { func (p *Poller[T, AggregateT]) Get(filter Filter) ([]*T, bool) {
return p.period.Get(filter) return p.period.Get(filter)
} }