package state import ( "context" "errors" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/trace" "gitea.libretechconsulting.com/rmcguire/ambient-local-exporter/pkg/weather" ) // Returns last requested number of weather updates func (w *WeatherState) Get(ctx context.Context, last int) ( []*weather.WeatherUpdate, error, ) { if last < 1 { last = 1 } ctx, span := w.tracer.Start(ctx, "getWeatherState") span.SetAttributes( attribute.Int("last", last), attribute.Int("keep", w.keep), attribute.Int("currentSize", w.Count()), ) defer span.End() updates, err := w.get(ctx, last) if err != nil { span.RecordError(err) span.SetStatus(codes.Error, err.Error()) } else { span.SetStatus(codes.Ok, "") } return updates, err } func (w *WeatherState) get(ctx context.Context, last int) ( []*weather.WeatherUpdate, error, ) { span := trace.SpanFromContext(ctx) w.RLock() defer w.Unlock() span.AddEvent("acquired lock on state cache") updates := w.updates if w.count() == 0 { err := errors.New("no state to get") span.RecordError(err) return nil, err } else if w.count() <= last { span.RecordError(errors.New("requested more state than exists")) } else { updates = updates[len(updates)-last:] } span.SetAttributes(attribute.Int("retrieved", len(updates))) span.SetStatus(codes.Ok, "") return updates, nil } // Returns count of retained weather updates func (w *WeatherState) Count() int { _, span := w.tracer.Start(w.ctx, "countWeatherState") defer span.End() count := w.count() span.SetAttributes(attribute.Int("count", count)) span.SetStatus(codes.Ok, "") return count } func (w *WeatherState) count() int { w.RLock() defer w.RUnlock() return len(w.updates) }