Files
gitlab-ce/lib/idempotency_cache.rb
2025-04-17 21:11:31 +00:00

49 lines
1.2 KiB
Ruby

# frozen_string_literal: true
# rubocop:disable Gitlab/NamespacedClass -- generic code
# rubocop:disable Gitlab/BoundedContexts -- generic code
class IdempotencyCache
# When code is wrapped with ensure_idempotency it won't be
# called again within the TTL(time to live) for the same key
# if the operation was successful completed
#
# Example:
# IdempotencyCache.ensure_idempotency("tracking_cache:#{build_id}", 5.hours)
# # idempotent within the TTL
# # wont run again if it ran successfully for that build within 5 hours
# track(params)
# end
def self.ensure_idempotency(key, ttl)
return if already_completed?(key)
result = yield
new(key, ttl).mark_as_completed!
result
end
def self.already_completed?(key)
Gitlab::Redis::SharedState.with do |redis|
redis.exists?(key) # rubocop:disable CodeReuse/ActiveRecord -- not active record
end
end
def initialize(key, ttl)
@key = key
@ttl = ttl
end
def mark_as_completed!
Gitlab::Redis::SharedState.with do |redis|
redis.set(
@key,
1,
ex: @ttl
)
end
end
end
# rubocop:enable Gitlab/NamespacedClass
# rubocop:enable Gitlab/BoundedContexts