summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorStan Hu <stanhu@gmail.com>2017-12-09 01:01:42 -0800
committerStan Hu <stanhu@gmail.com>2017-12-12 15:07:25 -0800
commit54f13b1ec8542dc5085e0367734e8344c2c3d01e (patch)
treeb5557f077e3d1d13e7148a5eaba682b9000153ca /lib
parentf8c3a58a54d622193a0cf15777a0d0631289278c (diff)
downloadgitlab-ce-54f13b1ec8542dc5085e0367734e8344c2c3d01e.tar.gz
Add rate limiting to guard against excessive scheduling of pipelines
Diffstat (limited to 'lib')
-rw-r--r--lib/gitlab/action_rate_limiter.rb31
1 files changed, 31 insertions, 0 deletions
diff --git a/lib/gitlab/action_rate_limiter.rb b/lib/gitlab/action_rate_limiter.rb
new file mode 100644
index 00000000000..c3af583a3ed
--- /dev/null
+++ b/lib/gitlab/action_rate_limiter.rb
@@ -0,0 +1,31 @@
+module Gitlab
+ # This class implements a simple rate limiter that can be used to throttle
+ # certain actions. Unlike Rack Attack and Rack::Throttle, which operate at
+ # the middleware level, this can be used at the controller level.
+ class ActionRateLimiter
+ TIME_TO_EXPIRE = 60 # 1 min
+
+ attr_accessor :action, :expiry_time
+
+ def initialize(action:, expiry_time: TIME_TO_EXPIRE)
+ @action = action
+ @expiry_time = expiry_time
+ end
+
+ def increment(key)
+ value = 0
+
+ Gitlab::Redis::Cache.with do |redis|
+ cache_key = "action_rate_limiter:#{action}:#{key}"
+ value = redis.incr(cache_key)
+ redis.expire(cache_key, expiry_time) if value == 1
+ end
+
+ value.to_i
+ end
+
+ def throttled?(key, threshold_value)
+ self.increment(key) > threshold_value
+ end
+ end
+end