2019-05-03 06:17:27 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2013-07-29 10:25:19 +08:00
|
|
|
class DistributedMemoizer
|
|
|
|
# never wait for longer that 1 second for a cross process lock
|
2022-04-06 01:29:58 +08:00
|
|
|
MAX_WAIT = 1
|
2013-07-29 10:25:19 +08:00
|
|
|
|
|
|
|
# memoize a key across processes and machines
|
2022-04-06 01:29:58 +08:00
|
|
|
def self.memoize(key, duration = 60 * 60 * 24, redis = Discourse.redis)
|
|
|
|
redis_lock_key = self.redis_lock_key(key)
|
2013-07-29 10:25:19 +08:00
|
|
|
redis_key = self.redis_key(key)
|
|
|
|
|
2022-04-06 01:29:58 +08:00
|
|
|
DistributedMutex.synchronize(redis_lock_key, redis: redis, validity: MAX_WAIT) do
|
|
|
|
result = redis.get(redis_key)
|
2013-11-26 07:21:41 +08:00
|
|
|
|
2022-04-06 01:29:58 +08:00
|
|
|
unless result
|
|
|
|
result = yield
|
|
|
|
redis.setex(redis_key, duration, result)
|
2013-07-29 10:25:19 +08:00
|
|
|
end
|
|
|
|
|
2022-04-06 01:29:58 +08:00
|
|
|
result
|
|
|
|
end
|
2013-07-29 10:25:19 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.redis_lock_key(key)
|
2022-04-06 01:29:58 +08:00
|
|
|
"memoize_lock_#{key}"
|
2013-07-29 10:25:19 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.redis_key(key)
|
2022-04-06 01:29:58 +08:00
|
|
|
"memoize_#{key}"
|
2013-07-29 10:25:19 +08:00
|
|
|
end
|
|
|
|
end
|