package grpc import ( "context" "go.opentelemetry.io/otel/attribute" otelcodes "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/trace" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/timestamppb" "gitea.libretechconsulting.com/rmcguire/go-app/pkg/otel" pb "gitea.libretechconsulting.com/rmcguire/ambient-local-exporter/api/v1alpha1/weather" "gitea.libretechconsulting.com/rmcguire/ambient-local-exporter/pkg/weather/recorder" ) type GRPCWeather struct { ctx context.Context recorder *recorder.WeatherRecorder tracer trace.Tracer *pb.UnimplementedAmbientLocalWeatherServiceServer } func NewGRPCWeather(ctx context.Context, recorder *recorder.WeatherRecorder) *GRPCWeather { return &GRPCWeather{ ctx: ctx, recorder: recorder, tracer: otel.GetTracer(ctx, "grpcWeather"), } } func (w *GRPCWeather) GetWeather(ctx context.Context, req *pb.GetWeatherRequest) ( *pb.GetWeatherResponse, error, ) { ctx, span := w.tracer.Start(ctx, "getWeather") defer span.End() limit := 1 if req.Limit != nil { if *req.Limit > 1 { limit = int(*req.Limit) } } span.SetAttributes(attribute.Int("limit", limit)) updates, err := w.recorder.Get(ctx, req) if err != nil { span.RecordError(err) span.SetStatus(otelcodes.Error, err.Error()) return nil, status.Error(codes.Internal, err.Error()) } else if len(updates) < 1 { return nil, status.Error(codes.OutOfRange, "no weather available") } span.SetStatus(otelcodes.Ok, "") return &pb.GetWeatherResponse{ LastUpdated: ×tamppb.Timestamp{ Seconds: updates[0].DateUTC.Unix(), }, WeatherUpdates: UpdatesToPbUpdates(updates), }, nil }