# frozen_string_literal: true module Ops # Campioni latenza GET /up (edge → rails) per calcolo p95. class UpLatencyTracker REDIS_KEY = "ops:up_latency_ms" MAX_SAMPLES = -> { ENV.fetch("OPS_UP_LATENCY_SAMPLES", "60").to_i } class << self def record(latency_ms) return unless redis redis.pipelined do |pipe| pipe.lpush(REDIS_KEY, latency_ms.to_i) pipe.ltrim(REDIS_KEY, 0, MAX_SAMPLES.call - 1) end end def samples return [] unless redis redis.lrange(REDIS_KEY, 0, -1).map(&:to_i) end def sample_count samples.size end def p95 sorted = samples.sort return nil if sorted.empty? index = [(sorted.size * 0.95).ceil - 1, 0].max sorted[index] end def redis @redis ||= Redis.new(url: ENV.fetch("REDIS_URL", "redis://localhost:6379/0")) rescue Redis::CannotConnectError nil end end end end