class Rodauth::OAuth::TtlStore

The TTL store is a data structure which keeps data by a key, and with a time-to-live. It is specifically designed for data which is static, i.e. for a certain key in a sufficiently large span, the value will be the same.

Because of that, synchronizations around reads do not exist, while write synchronizations will be short-circuited by a read.

Constants

DEFAULT_TTL

Public Class Methods

new() click to toggle source
# File lib/rodauth/oauth/ttl_store.rb, line 14
def initialize
  @store_mutex = Mutex.new
  @store = {}
end

Public Instance Methods

[](key) click to toggle source
# File lib/rodauth/oauth/ttl_store.rb, line 19
def [](key)
  lookup(key, now)
end
set(key, &block) click to toggle source
# File lib/rodauth/oauth/ttl_store.rb, line 23
def set(key, &block)
  @store_mutex.synchronize do
    # short circuit
    return @store[key][:payload] if @store[key] && @store[key][:ttl] < now
  end

  payload, ttl = block.call

  @store_mutex.synchronize do
    # given that the block call triggers network, and two requests for the same key be processed
    # at the same time, this ensures the first one wins.
    return @store[key][:payload] if @store[key] && @store[key][:ttl] < now

    @store[key] = { payload: payload, ttl: (ttl || (now + DEFAULT_TTL)) }
  end
  @store[key][:payload]
end
uncache(key) click to toggle source
# File lib/rodauth/oauth/ttl_store.rb, line 41
def uncache(key)
  @store_mutex.synchronize do
    @store.delete(key)
  end
end

Private Instance Methods

lookup(key, ttl) click to toggle source

do not use directly!

# File lib/rodauth/oauth/ttl_store.rb, line 54
def lookup(key, ttl)
  return unless @store.key?(key)

  value = @store[key]

  return if value.empty?

  return unless value[:ttl] > ttl

  value[:payload]
end
now() click to toggle source
# File lib/rodauth/oauth/ttl_store.rb, line 49
def now
  Process.clock_gettime(Process::CLOCK_MONOTONIC)
end