Files
gitlab-foss/lib/gitlab/utils/redis_throttle.rb
2025-06-03 12:19:01 +00:00

35 lines
1.4 KiB
Ruby

# frozen_string_literal: true
module Gitlab
module Utils
class RedisThrottle
# Executes a block of code at most once within a given time period using Redis for throttling.
# This is useful for scheduled tasks that should not execute too frequently.
#
# @param [ActiveSupport::Duration, Integer] period: The minimum time period between executions
# @param [String] cache_key: The key to use for Redis caching (must be unique for each distinct operation)
# @param [Boolean] skip_in_development: If true, always executes in development environment (default: true)
# @param [Proc] block: The code to execute if throttling conditions are met
#
# @return [Object, false] The result of the block or false if execution was throttled
#
# @example Execute a task at most once every hour
# Gitlab::Utils::RedisThrottle.execute_every(1.hour, 'my_task:hourly_job') do
# puts "This will run once per hour"
# end
#
def self.execute_every(period, cache_key, skip_in_development: true)
return yield if skip_in_development && Rails.env.development?
return yield unless period
Gitlab::Redis::SharedState.with do |redis|
key_set = redis.set(cache_key, 1, ex: period, nx: true)
break false unless key_set
yield
end
end
end
end
end