From 47c44356f8672a138a306aa81923568f9e4f1a04 Mon Sep 17 00:00:00 2001 From: Sam Date: Thu, 7 Dec 2017 11:48:11 +1100 Subject: [PATCH] FIX: load balanced servers do not share monotonic clock This means then when a service is load balanced and you reach rate limits there was a case where they counting was way off also remove the stub from clock_gettime cause we need to be super careful with it, so we should probably just stub by hand when needed --- lib/rate_limiter.rb | 8 ++++---- spec/rails_helper.rb | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/rate_limiter.rb b/lib/rate_limiter.rb index 65edfd64df9..a9d82a959ad 100644 --- a/lib/rate_limiter.rb +++ b/lib/rate_limiter.rb @@ -7,7 +7,7 @@ class RateLimiter attr_reader :max, :secs, :user, :key def self.key_prefix - "l-rate-limit2:" + "l-rate-limit3:" end def self.disable @@ -76,7 +76,7 @@ class RateLimiter def performed! return if rate_unlimited? - now = Process.clock_gettime(Process::CLOCK_MONOTONIC).to_i + now = Time.now.to_i if eval_lua(PERFORM_LUA, PERFORM_LUA_SHA, [prefixed_key], [now, @secs, @max]) == 0 raise RateLimiter::LimitExceeded.new(seconds_to_wait, @type) end @@ -97,7 +97,7 @@ class RateLimiter return @max if @user && @user.staff? arr = redis.lrange(prefixed_key, 0, @max) || [] - t0 = Process.clock_gettime(Process::CLOCK_MONOTONIC).to_i + t0 = Time.now.to_i arr.reject! { |a| (t0 - a.to_i) > @secs } @max - arr.size end @@ -122,7 +122,7 @@ class RateLimiter def age_of_oldest # age of oldest event in buffer, in seconds - Process.clock_gettime(Process::CLOCK_MONOTONIC).to_i - redis.lrange(prefixed_key, -1, -1).first.to_i + Time.now.to_i - redis.lrange(prefixed_key, -1, -1).first.to_i end def is_under_limit? diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index c56ed93005e..d2b575f2944 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -203,7 +203,6 @@ def freeze_time(now = Time.now) Time.stubs(:now).returns(time) Date.stubs(:today).returns(datetime.to_date) TrackTimeStub.stubs(:stubbed).returns(true) - Process.stubs(:clock_gettime).with(Process::CLOCK_MONOTONIC).returns(datetime.to_f) if block_given? begin @@ -219,7 +218,6 @@ def unfreeze_time Time.unstub(:now) Date.unstub(:today) TrackTimeStub.unstub(:stubbed) - Process.unstub(:clock_gettime) end def file_from_fixtures(filename, directory = "images")