class Matador::Fetcher

Attributes

block[R]
key[R]
therd_ttl[R]
ttl[R]

Public Class Methods

new(key, options, block) click to toggle source
# File lib/matador/fetcher.rb, line 5
def initialize(key, options, block)
  @key = key
  @ttl = options[:ttl]
  @therd_ttl = options[:therd_ttl]
  @block = block
end

Public Instance Methods

perform() click to toggle source
# File lib/matador/fetcher.rb, line 12
def perform
  if (cache_valid? && (valid_cache = current_cache))
    valid_cache
  elsif !(cache_valid? || locked_for_rebuilding_cache?)
    # cache just expired but no request has gone through yet
    rebuild_cache_with_first_request
  elsif (locked_for_rebuilding_cache? && (stale_value = current_cache))
    # first request already went through
    # serving up stale value while new cache is built
    stale_value
  else  
    # fallback case (this should be a rare occurence)
    # Happens if therd_ttl isn't long enough
    # or cache_store evicted key
    # or cache_store failed to save key in the first place
    
    if locked_for_rebuilding_cache?
      # already rebuilding cache so just return the value
      block.call 
    else
      # have not started rebuilding cache
      # so this becomes the "first request"
      rebuild_cache_with_first_request 
    end
  end
end

Private Instance Methods

cache_store() click to toggle source
# File lib/matador/fetcher.rb, line 52
def cache_store
  Matador.cache_store
end
cache_valid?() click to toggle source
# File lib/matador/fetcher.rb, line 44
def cache_valid?
  !!cache_store.get(key_nominal_ttl)
end
current_cache() click to toggle source
# File lib/matador/fetcher.rb, line 48
def current_cache
  cache_store.get(key)
end
key_nominal_ttl() click to toggle source
# File lib/matador/fetcher.rb, line 84
def key_nominal_ttl
  "matador:nominal_ttl:#{key}"
end
key_rebuilding() click to toggle source
# File lib/matador/fetcher.rb, line 88
def key_rebuilding
  "matador:rebuilding:#{key}"
end
lock_rebuilding_cache() click to toggle source
# File lib/matador/fetcher.rb, line 75
def lock_rebuilding_cache
  cache_store.set(key_rebuilding, "1") 
  cache_store.expire(key_rebuilding, therd_ttl)
end
locked_for_rebuilding_cache?() click to toggle source
# File lib/matador/fetcher.rb, line 40
def locked_for_rebuilding_cache?
  !!cache_store.get(key_rebuilding)
end
rebuild_cache_with_first_request() click to toggle source
# File lib/matador/fetcher.rb, line 56
def rebuild_cache_with_first_request
  lock_rebuilding_cache
  
  new_value = block.call
  # compute new value

  cache_store.set(key, new_value)
  cache_store.expire(key, ttl + therd_ttl)
  # cache new value and expire accordingly
 
  cache_store.set(key_nominal_ttl, "1")
  cache_store.expire(key_nominal_ttl, ttl)
  # set the nominal (ie. end user) ttl

  unlock_rebuilding_cache

  new_value
end
unlock_rebuilding_cache() click to toggle source
# File lib/matador/fetcher.rb, line 80
def unlock_rebuilding_cache
  cache_store.del(key_rebuilding)
end