implement redis and noop recorders
All checks were successful
Build and Publish / check-chart (push) Successful in 20s
Build and Publish / helm-release (push) Has been skipped
Build and Publish / release (push) Successful in 4m12s

This commit is contained in:
Ryan McGuire 2025-03-22 14:29:24 -04:00
parent 46a213f314
commit 6e1ec0b5c1
8 changed files with 45 additions and 17 deletions

View File

@ -86,12 +86,18 @@
"ConfigRecorderConfig": {
"properties": {
"keepLast": {
"default": 120,
"type": "integer"
},
"redisConfig": {
"$ref": "#/definitions/ConfigRedisConfig"
},
"type": {
"enum": [
"memory",
"redis",
"noop"
],
"type": "string"
}
},

View File

@ -91,9 +91,10 @@ func (aw *AmbientWeather) Init() *AmbientWeather {
}
aw.weatherRecorder = recorder.MustNewWeatherRecorder(&recorder.Opts{
Ctx: aw.appCtx,
KeepLast: updatesToKeep,
Recorder: r,
AppConfig: aw.Config,
Ctx: aw.appCtx,
KeepLast: updatesToKeep,
Recorder: r,
})
aw.l.Trace().Any("awConfig", aw.Config).Send()

View File

@ -9,9 +9,9 @@ const (
)
type RecorderConfig struct {
Type RecorderType `yaml:"type" env:"RECORDER_TYPE" json:"type,omitempty"` // memory|redis
KeepLast int `yaml:"keepLast" env:"RECORDER_KEEP_LAST" json:"keepLast,omitempty"`
RedisConfig *RedisConfig `json:"redisConfig,omitempty"`
Type RecorderType `yaml:"type" env:"RECORDER_TYPE" json:"type,omitempty" enum:"memory,redis,noop"`
KeepLast int `yaml:"keepLast" env:"RECORDER_KEEP_LAST" json:"keepLast,omitempty" default:"120"`
RedisConfig *RedisConfig `yaml:"redisConfig,omitempty" json:"redisConfig,omitempty"`
}
type RedisConfig struct {

View File

@ -4,11 +4,13 @@ import (
"context"
"sync"
"github.com/rs/zerolog"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/trace"
"gitea.libretechconsulting.com/rmcguire/go-app/pkg/otel"
"gitea.libretechconsulting.com/rmcguire/ambient-local-exporter/pkg/ambient/config"
"gitea.libretechconsulting.com/rmcguire/ambient-local-exporter/pkg/weather/recorder/recorders"
)
@ -21,9 +23,10 @@ type WeatherRecorder struct {
}
type Opts struct {
Ctx context.Context
Recorder recorders.Recorder // If nil, will use memory recorder
KeepLast int
AppConfig *config.AmbientLocalExporterConfig
Ctx context.Context
Recorder recorders.Recorder // If nil, will use memory recorder
KeepLast int
}
func MustNewWeatherRecorder(opts *Opts) *WeatherRecorder {
@ -36,10 +39,14 @@ func MustNewWeatherRecorder(opts *Opts) *WeatherRecorder {
}
opts.Recorder.Init(opts.Ctx, &recorders.RecorderOpts{
AppConfig: opts.AppConfig,
RetainLast: opts.KeepLast,
BaseCtx: opts.Ctx,
})
zerolog.Ctx(opts.Ctx).Info().Str("recorderType", opts.Recorder.Name()).
Msg("weather update recorder ready")
return &WeatherRecorder{
ctx: opts.Ctx,
recorder: opts.Recorder,

View File

@ -12,7 +12,10 @@ import (
"gitea.libretechconsulting.com/rmcguire/ambient-local-exporter/pkg/weather/recorder/recorders"
)
const defRetainLast = 120
const (
DEF_RETAIN_LAST = 120
NAME = "memory recorder"
)
type MemoryRecorder struct {
baseCtx context.Context
@ -24,7 +27,7 @@ type MemoryRecorder struct {
func (r *MemoryRecorder) Init(ctx context.Context, opts *recorders.RecorderOpts) {
if opts.RetainLast < 1 {
opts.RetainLast = defRetainLast
opts.RetainLast = DEF_RETAIN_LAST
}
r.updates = make([]*weather.WeatherUpdate, 0, opts.RetainLast)
@ -33,3 +36,5 @@ func (r *MemoryRecorder) Init(ctx context.Context, opts *recorders.RecorderOpts)
r.RWMutex = &sync.RWMutex{}
r.tracer = otel.GetTracer(r.baseCtx, "memoryRecorder")
}
func (r *MemoryRecorder) Name() string { return NAME }

View File

@ -19,3 +19,5 @@ func (n *NoopRecorder) Get(context.Context, *pb.GetWeatherRequest) ([]*weather.W
}
func (n *NoopRecorder) Count(context.Context) int { return 0 }
func (r *NoopRecorder) Name() string { return "no-op recorder" }

View File

@ -19,4 +19,5 @@ type Recorder interface {
Set(context.Context, *weather.WeatherUpdate) error
Get(context.Context, *pb.GetWeatherRequest) ([]*weather.WeatherUpdate, error)
Count(context.Context) int // Best Effort
Name() string
}

View File

@ -22,6 +22,7 @@ import (
const (
DEF_RETAIN = 120
UPDATES_KEY = "weatherUpdates"
NAME = "redis recorder"
)
type RedisRecorder struct {
@ -36,11 +37,19 @@ type RedisRecorder struct {
}
func (r *RedisRecorder) Init(ctx context.Context, opts *recorders.RecorderOpts) {
if opts.AppConfig.RecorderConfig.RedisConfig == nil {
panic("refusing to init redis recorder with no redisConfig")
}
if opts.RetainLast < 1 {
opts.RetainLast = DEF_RETAIN
}
r.log = zerolog.Ctx(opts.BaseCtx)
r.config = opts.AppConfig
r.keep = opts.RetainLast
r.RWMutex = &sync.RWMutex{}
r.baseCtx = opts.BaseCtx
r.log = zerolog.Ctx(r.baseCtx)
r.tracer = otel.GetTracer(r.baseCtx, "redisRecorder")
ctx, span := r.tracer.Start(ctx, "redisRecorder.init", trace.WithAttributes(
@ -51,11 +60,6 @@ func (r *RedisRecorder) Init(ctx context.Context, opts *recorders.RecorderOpts)
))
defer span.End()
r.config = opts.AppConfig
r.keep = opts.RetainLast
r.baseCtx = opts.BaseCtx
r.RWMutex = &sync.RWMutex{}
// Unique key prefix for this version/env/name of exporter
// will be consistent across replicas, but resets on upgrade
// as it is using version
@ -106,3 +110,5 @@ func (r *RedisRecorder) MustInitRedis(ctx context.Context) {
func (r *RedisRecorder) Key() string {
return fmt.Sprintf("%s:%s", r.appKey, UPDATES_KEY)
}
func (r *RedisRecorder) Name() string { return NAME }