mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-07-23 00:47:51 +00:00
35 lines
1.4 KiB
Ruby
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
|