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:
2025-03-22 14:29:24 -04:00
parent 46a213f314
commit 6e1ec0b5c1
8 changed files with 45 additions and 17 deletions

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 }