class HTTPClient::LRUCache

Attributes

max_size[R]
retry_delay[R]
soft_ttl[R]
ttl[R]

Public Class Methods

new(opts={}) click to toggle source
# File lib/httpclient/lru_cache.rb, line 14
def initialize(opts={})
  @mutex = Mutex.new

  @max_size = Integer(opts[:max_size] || 100)
  @ttl = Float(opts[:ttl] || 0)
  @soft_ttl = Float(opts[:soft_ttl] || 0)
  @retry_delay = Float(opts[:retry_delay] || 0)

  raise "max_size must not be negative" if @max_size < 0
  raise "ttl must not be negative" if @ttl < 0
  raise "soft_ttl must not be negative" if @soft_ttl < 0
  raise "retry_delay must not be negative" if @retry_delay < 0

  # we don't use thread safe variant, as we're doing thread safety ourselves
  @data = LruRedux::Cache.new(@max_size)
end

Public Instance Methods

fetch(key) { || ... } click to toggle source
# File lib/httpclient/lru_cache.rb, line 31
def fetch(key)
  # for now, this means that DNS resolving is single-threaded
  @mutex.synchronize do
    datum = @data[key]
    if datum.nil?
      store(key, value = yield)
    elsif datum.expired?
      @data.delete(key)
      store(key, value = yield)
    elsif datum.soft_expired?
      begin
        store(key, value = yield)
      rescue RuntimeError => e
        datum.soft_expiration = (Time.now + retry_delay) if retry_delay > 0
        datum.value
      end
    else
      datum.value
    end
  end
end

Private Instance Methods

store(key, value) click to toggle source
# File lib/httpclient/lru_cache.rb, line 55
def store(key, value)
  expiration = Time.now + @ttl
  soft_expiration = Time.now + @soft_ttl
  @data[key] = Datum.new(value, expiration, soft_expiration)
  value
end