mirror of
https://github.com/yusing/godoxy.git
synced 2026-01-11 22:30:47 +01:00
refactor(metrics): remove pointers from type parameter T to avoid unnecessary indirection
This commit is contained in:
@@ -6,7 +6,7 @@ import (
|
||||
)
|
||||
|
||||
type Entries[T any] struct {
|
||||
entries [maxEntries]*T
|
||||
entries [maxEntries]T
|
||||
index int
|
||||
count int
|
||||
interval time.Duration
|
||||
@@ -16,17 +16,14 @@ type Entries[T any] struct {
|
||||
const maxEntries = 100
|
||||
|
||||
func newEntries[T any](duration time.Duration) *Entries[T] {
|
||||
interval := duration / maxEntries
|
||||
if interval < time.Second {
|
||||
interval = time.Second
|
||||
}
|
||||
interval := max(duration/maxEntries, time.Second)
|
||||
return &Entries[T]{
|
||||
interval: interval,
|
||||
lastAdd: time.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Entries[T]) Add(now time.Time, info *T) {
|
||||
func (e *Entries[T]) Add(now time.Time, info T) {
|
||||
if now.Sub(e.lastAdd) < e.interval {
|
||||
return
|
||||
}
|
||||
@@ -38,11 +35,11 @@ func (e *Entries[T]) Add(now time.Time, info *T) {
|
||||
e.lastAdd = now
|
||||
}
|
||||
|
||||
func (e *Entries[T]) Get() []*T {
|
||||
func (e *Entries[T]) Get() []T {
|
||||
if e.count < maxEntries {
|
||||
return e.entries[:e.count]
|
||||
}
|
||||
res := make([]*T, maxEntries)
|
||||
res := make([]T, maxEntries)
|
||||
copy(res, e.entries[e.index:])
|
||||
copy(res[maxEntries-e.index:], e.entries[:e.index])
|
||||
return res
|
||||
@@ -57,7 +54,7 @@ func (e *Entries[T]) MarshalJSON() ([]byte, error) {
|
||||
|
||||
func (e *Entries[T]) UnmarshalJSON(data []byte) error {
|
||||
var v struct {
|
||||
Entries []*T `json:"entries"`
|
||||
Entries []T `json:"entries"`
|
||||
Interval time.Duration `json:"interval"`
|
||||
}
|
||||
if err := json.Unmarshal(data, &v); err != nil {
|
||||
|
||||
@@ -3,6 +3,7 @@ package period
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -29,6 +30,7 @@ type ResponseType[AggregateT any] struct {
|
||||
//
|
||||
// If the request is a websocket request, it serves the data for the given period for every interval.
|
||||
func (p *Poller[T, AggregateT]) ServeHTTP(c *gin.Context) {
|
||||
period := Filter(c.Query("period"))
|
||||
query := c.Request.URL.Query()
|
||||
|
||||
if httpheaders.IsWebsocket(c.Request.Header) {
|
||||
@@ -42,10 +44,10 @@ func (p *Poller[T, AggregateT]) ServeHTTP(c *gin.Context) {
|
||||
interval = minInterval
|
||||
}
|
||||
websocket.PeriodicWrite(c, interval, func() (any, error) {
|
||||
return p.getRespData(c.Request)
|
||||
return p.getRespData(period, query)
|
||||
})
|
||||
} else {
|
||||
data, err := p.getRespData(c.Request)
|
||||
data, err := p.getRespData(period, query)
|
||||
if err != nil {
|
||||
c.Error(apitypes.InternalServerError(err, "failed to get response data"))
|
||||
return
|
||||
@@ -58,13 +60,11 @@ func (p *Poller[T, AggregateT]) ServeHTTP(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Poller[T, AggregateT]) getRespData(r *http.Request) (any, error) {
|
||||
query := r.URL.Query()
|
||||
period := query.Get("period")
|
||||
func (p *Poller[T, AggregateT]) getRespData(period Filter, query url.Values) (any, error) {
|
||||
if period == "" {
|
||||
return p.GetLastResult(), nil
|
||||
}
|
||||
rangeData, ok := p.Get(Filter(period))
|
||||
rangeData, ok := p.Get(period)
|
||||
if !ok {
|
||||
return nil, errors.New("invalid period")
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ func NewPeriod[T any]() *Period[T] {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Period[T]) Add(info *T) {
|
||||
func (p *Period[T]) Add(info T) {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
now := time.Now()
|
||||
@@ -41,7 +41,7 @@ func (p *Period[T]) Add(info *T) {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Period[T]) Get(filter Filter) ([]*T, bool) {
|
||||
func (p *Period[T]) Get(filter Filter) ([]T, bool) {
|
||||
p.mu.RLock()
|
||||
defer p.mu.RUnlock()
|
||||
period, ok := p.Entries[filter]
|
||||
|
||||
@@ -17,16 +17,16 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
PollFunc[T any] func(ctx context.Context, lastResult *T) (*T, error)
|
||||
AggregateFunc[T any, AggregateT json.Marshaler] func(entries []*T, query url.Values) (total int, result AggregateT)
|
||||
FilterFunc[T any] func(entries []*T, keyword string) (filtered []*T)
|
||||
PollFunc[T any] func(ctx context.Context, lastResult T) (T, error)
|
||||
AggregateFunc[T any, AggregateT json.Marshaler] func(entries []T, query url.Values) (total int, result AggregateT)
|
||||
FilterFunc[T any] func(entries []T, keyword string) (filtered []T)
|
||||
Poller[T any, AggregateT json.Marshaler] struct {
|
||||
name string
|
||||
poll PollFunc[T]
|
||||
aggregate AggregateFunc[T, AggregateT]
|
||||
resultFilter FilterFunc[T]
|
||||
period *Period[T]
|
||||
lastResult atomic.Value[*T]
|
||||
lastResult atomic.Value[T]
|
||||
errs []pollErr
|
||||
}
|
||||
pollErr struct {
|
||||
@@ -188,10 +188,10 @@ func (p *Poller[T, AggregateT]) Start() {
|
||||
}()
|
||||
}
|
||||
|
||||
func (p *Poller[T, AggregateT]) Get(filter Filter) ([]*T, bool) {
|
||||
func (p *Poller[T, AggregateT]) Get(filter Filter) ([]T, bool) {
|
||||
return p.period.Get(filter)
|
||||
}
|
||||
|
||||
func (p *Poller[T, AggregateT]) GetLastResult() *T {
|
||||
func (p *Poller[T, AggregateT]) GetLastResult() T {
|
||||
return p.lastResult.Load()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user