+3
−2
Loading
Consolidate INCR/EXPIRE/TTL into a single EVAL call and extend the counter primitive to INCRBYFLOAT with a per-call cost parameter. The script runs atomically from Redis's perspective, eliminating the latent race between increment and EXPIRE in the prior pipelined implementation. Adds `cost:` keyword to Limiter#check and Labkit::RateLimit.check; default 1 preserves existing call-site semantics. cost=0 short-circuits to a GET so resource-usage callers that observed zero usage do not allocate a Redis key. ttl_before < 0 self-heals keys left without expiry by any prior bug. EVALSHA with NOSCRIPT fallback covers Redis restarts that wipe the script cache. spec/labkit/rate_limit/evaluator_spec.rb is rewritten from mock-based to TestRedis-backed, matching rate_limit_spec.rb's idiom now that real Redis test infrastructure is available. Recommend reading the new file as a standalone, not as a line-by-line diff. BREAKING CHANGE: Result::Info#count is now Float (previously Integer). INCRBYFLOAT returns a string-encoded number that the evaluator parses as Float for both integer-valued and fractional counters. to_response_headers coerces remaining/limit back to Integer per the RateLimit header spec. Numeric comparisons against Integer thresholds work unchanged via Ruby coercion; pattern-matching on Integer type will break and must be updated. Refs gitlab-com/gl-infra/production-engineering#28827