mirror of
https://github.com/gitlabhq/gitlabhq.git
synced 2025-07-20 16:42:55 +00:00
49 lines
1.2 KiB
Ruby
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
|