Class: APICache

Inherits:
Object
  • Object
show all
Defined in:
lib/api_cache.rb,
lib/api_cache/api.rb,
lib/api_cache/cache.rb,
lib/api_cache/null_store.rb,
lib/api_cache/dalli_store.rb,
lib/api_cache/memory_store.rb,
lib/api_cache/moneta_store.rb,
lib/api_cache/abstract_store.rb

Overview

Contains the complete public API for APICache.

See APICache.get method and the README file.

Before using APICache you should set the store to use using APICache.store=. For convenience, when no store is set an in memory store will be used (and a warning will be logged).

Defined Under Namespace

Classes: API, APICacheError, AbstractStore, Cache, CannotFetch, DalliStore, InvalidResponse, MemoryStore, MonetaStore, NotAvailableError, NullStore, TimeoutError

Class Attribute Summary (collapse)

Class Method Summary (collapse)

Class Attribute Details

+ (Object) logger

:nodoc:



22
23
24
# File 'lib/api_cache.rb', line 22

def logger
  @logger
end

+ (Object) store

:nodoc:



37
38
39
# File 'lib/api_cache.rb', line 37

def store
  @store
end

Class Method Details

+ (Object) delete(key)

Manually delete data from the cache.



134
135
136
# File 'lib/api_cache.rb', line 134

def self.delete(key)
  APICache::Cache.new(key, {}).delete
end

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

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 any exception - 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 returned.

An exception will be raised if the API cannot be fetched and the request cannot be served by the cache. This will either be a subclass of APICache::Error or an exception raised by the provided block.

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


82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/api_cache.rb', line 82

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 = APICache::Cache.new(key, {
    :cache => options[:cache],
    :valid => options[:valid]
  })

  api = APICache::API.new(key, {
    :period => options[:period],
    :timeout => options[:timeout]
  }, &block)

  cache_state = cache.state

  if cache_state == :current
    APICache.logger.debug "APICache #{@key}: Returning from cache"
    cache.get
  else
    begin
      value = api.get
      cache.set(value)
      value
    rescue => e
      APICache.logger.info "APICache #{key}: Exception raised (#{e.message} - #{e.class})" \

      # No point outputting backgraces for internal APICache errors
      APICache.logger.debug "Backtrace:\n#{e.backtrace.join("\n")}" unless e.kind_of?(APICacheError)

      if cache_state == :refetch
        cache.get
      else
        APICache.logger.warn "APICache #{key}: Data not available in the cache or from API"
        if options.has_key?(:fail)
          fail = options[:fail]
          fail.respond_to?(:call) ? fail.call : fail
        else
          raise e
        end
      end
    end
  end
end