Class: APICache

Inherits:
Object
  • Object
show all
Defined in:
lib/api_cache.rb

Defined Under Namespace

Classes: API, AbstractStore, Cache, CannotFetch, Invalid, Logger, MemcacheStore, MemoryStore, NotAvailableError

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.apiObject

Returns the value of attribute api.



8
9
10
# File 'lib/api_cache.rb', line 8

def api
  @api
end

.cacheObject

Returns the value of attribute cache.



7
8
9
# File 'lib/api_cache.rb', line 7

def cache
  @cache
end

.loggerObject

Returns the value of attribute logger.



9
10
11
# File 'lib/api_cache.rb', line 9

def logger
  @logger
end

Class Method Details

.get(key, options = {}, &block) ⇒ Object

Raises an APICache::NotAvailableError if it can’t get a value. You should rescue this if your application code.

Optionally call with a block. The value of the block is then used to set the cache rather than calling the url. Use it for example if you need to make another type of request, catch custom error codes etc. To signal that the call failed just raise APICache::Invalid - the value will then not be cached and the api will not be called again for options seconds. If an old value is available in the cache then it will be used.

For example:

APICache.get("http://twitter.com/statuses/user_timeline/6869822.atom")

APICache.get \
  "http://twitter.com/statuses/user_timeline/6869822.atom",
  :cache => 60, :valid => 600


35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/api_cache.rb', line 35

def self.get(key, options = {}, &block)
  options = {
    :cache => 600,    # 10 minutes  After this time fetch new data
    :valid => 86400,  # 1 day       Maximum time to use old data
                      #             :forever is a valid option
    :period => 60,    # 1 minute    Maximum frequency to call API
    :timeout => 5     # 5 seconds   API response timeout
  }.merge(options)
  
  cache_state = cache.state(key, options[:cache], options[:valid])
  
  if cache_state == :current
    cache.get(key)
  else
    begin
      raise APICache::CannotFetch unless api.queryable?(key, options[:period])
      value = api.get(key, options[:timeout], &block)
      cache.set(key, value)
      value
    rescue APICache::CannotFetch => e
      APICache.logger.log "Failed to fetch new data from API because " \
        "#{e.class}: #{e.message}"
      if cache_state == :refetch
        cache.get(key)
      else
        APICache.logger.log "Data not available in the cache or from API"
        raise APICache::NotAvailableError, e.message
      end
    end
  end
end

.start(store = APICache::MemcacheStore, logger = APICache::Logger.new) ⇒ Object

Initializes the cache



13
14
15
16
17
# File 'lib/api_cache.rb', line 13

def self.start(store = APICache::MemcacheStore, logger = APICache::Logger.new)
  APICache.logger = logger
  APICache.cache  = APICache::Cache.new(store)
  APICache.api    = APICache::API.new
end