diff --git a/internal/metrics/period/handler.go b/internal/metrics/period/handler.go index 9bff64f..af6ead0 100644 --- a/internal/metrics/period/handler.go +++ b/internal/metrics/period/handler.go @@ -31,7 +31,7 @@ func (p *Poller[T, AggregateT]) ServeHTTP(w http.ResponseWriter, r *http.Request minInterval := 1 * time.Second if interval == 0 { - interval = p.interval() + interval = pollInterval } if interval < minInterval { interval = minInterval @@ -66,11 +66,10 @@ func (p *Poller[T, AggregateT]) getRespData(r *http.Request) (any, error) { if period == "" { return p.GetLastResult(), nil } - periodFilter := Filter(period) - if !periodFilter.IsValid() { + rangeData, ok := p.Get(Filter(period)) + if !ok { return nil, errors.New("invalid period") } - rangeData := p.Get(periodFilter) if p.aggregator != nil { total, aggregated := p.aggregator(rangeData, query) return map[string]any{ diff --git a/internal/metrics/period/period.go b/internal/metrics/period/period.go index 9936a45..1efd48d 100644 --- a/internal/metrics/period/period.go +++ b/internal/metrics/period/period.go @@ -6,31 +6,21 @@ import ( ) type Period[T any] struct { - FiveMinutes *Entries[T] - FifteenMinutes *Entries[T] - OneHour *Entries[T] - OneDay *Entries[T] - OneMonth *Entries[T] - mu sync.RWMutex + Entries map[Filter]*Entries[T] + mu sync.RWMutex } 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] { return &Period[T]{ - FiveMinutes: newEntries[T](5 * time.Minute), - FifteenMinutes: newEntries[T](15 * time.Minute), - OneHour: newEntries[T](1 * time.Hour), - OneDay: newEntries[T](24 * time.Hour), - OneMonth: newEntries[T](30 * 24 * time.Hour), + Entries: map[Filter]*Entries[T]{ + "5m": newEntries[T](5 * time.Minute), + "15m": newEntries[T](15 * time.Minute), + "1h": newEntries[T](1 * 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() defer p.mu.Unlock() now := time.Now() - p.FiveMinutes.Add(now, info) - p.FifteenMinutes.Add(now, info) - p.OneHour.Add(now, info) - p.OneDay.Add(now, info) - p.OneMonth.Add(now, info) + for _, period := range p.Entries { + period.Add(now, info) + } } -func (p *Period[T]) Get(filter Filter) []*T { +func (p *Period[T]) Get(filter Filter) ([]*T, bool) { p.mu.RLock() defer p.mu.RUnlock() - switch filter { - case PeriodFiveMinutes: - return p.FiveMinutes.Get() - 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") + period, ok := p.Entries[filter] + if !ok { + return nil, false } -} - -func (filter Filter) IsValid() bool { - switch filter { - case PeriodFiveMinutes, PeriodFifteenMinutes, PeriodOneHour, PeriodOneDay, PeriodOneMonth: - return true - } - return false + return period.Get(), true } diff --git a/internal/metrics/period/poller.go b/internal/metrics/period/poller.go index 1388e41..7a2ef3e 100644 --- a/internal/metrics/period/poller.go +++ b/internal/metrics/period/poller.go @@ -30,7 +30,10 @@ type ( } ) -const gatherErrsInterval = 30 * time.Second +const ( + pollInterval = 1 * time.Second + gatherErrsInterval = 30 * time.Second +) func NewPoller[T any]( name string, @@ -61,10 +64,6 @@ func (p *Poller[T, AggregateT]) WithResultFilter(filter FilterFunc[T]) *Poller[T return p } -func (p *Poller[T, AggregateT]) interval() time.Duration { - return p.period.FiveMinutes.interval -} - func (p *Poller[T, AggregateT]) appendErr(err error) { if len(p.errs) == 0 { p.errs = []pollErr{ @@ -97,7 +96,7 @@ func (p *Poller[T, AggregateT]) clearErrs() { } func (p *Poller[T, AggregateT]) pollWithTimeout(ctx context.Context) { - ctx, cancel := context.WithTimeout(ctx, p.interval()) + ctx, cancel := context.WithTimeout(ctx, pollInterval) defer cancel() data, err := p.poll(ctx, p.lastResult) if err != nil { @@ -111,12 +110,12 @@ func (p *Poller[T, AggregateT]) pollWithTimeout(ctx context.Context) { func (p *Poller[T, AggregateT]) Start() { go func() { ctx := task.RootContext() - ticker := time.NewTicker(p.interval()) + ticker := time.NewTicker(pollInterval) gatherErrsTicker := time.NewTicker(gatherErrsInterval) defer ticker.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) @@ -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) }