Class: RightScale::CloudApi::CacheValidator
- Defined in:
- lib/base/routines/cache_validator.rb
Overview
The routine processes cache validations (when caching is enabled).
It takes a response from a cloud and tries to find a pre-defined caching pattern that would fit to this response and its request. If there is a pattern it extracts a previous response from the cache and compares it to the current one.
If both the responses match it raises RightScale::CloudApi::CacheHit exception.
The main point of the caching - it is performed before parsing a response. So if we get a 10M XML from Amazon it will take seconds to parse it but if the response did not change there is need to parse it.
The caching setting is per cloud specific ApiManager. For some of them it is on by default so you need to look at the ApiManager definition.
Defined Under Namespace
Modules: ClassMethods Classes: Error
Instance Attribute Summary
Attributes inherited from Routine
Instance Method Summary collapse
-
#log(message) ⇒ Object
Logs a message.
-
#process ⇒ Object
The main entry point.
Methods inherited from Routine
#cloud_api_logger, #execute, #invoke_callback_method, #options, #reset, #with_timer
Instance Method Details
#log(message) ⇒ Object
Logs a message.
57 58 59 |
# File 'lib/base/routines/cache_validator.rb', line 57 def log() cloud_api_logger.log( "#{message}", :cache_validator) end |
#process ⇒ Object
The main entry point.
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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/base/routines/cache_validator.rb', line 98 def process # Do nothing if caching is off return nil unless data[:options][:cache] # There is nothing to cache if we stream things return nil if data[:response][:instance].is_io? cache_patterns = data[:options][:cache_patterns] || [] opts = { :relative_path => data[:request][:relative_path], :request => data[:request][:instance], :response => data[:response][:instance], :verb => data[:request][:verb], :params => data[:request][:orig_params].dup } # Walk through all the cache patterns and find the first that matches cache_patterns.each do |pattern| # Try on the next pattern unless the current one matches. next unless Utils::pattern_matches?(pattern, opts) # Process the matching pattern. log("Request matches to cache pattern: #{pattern.inspect}") # Build a cache key and get a text to be signed cache_key, text_to_sign = build_cache_key(pattern, opts) cache_record = { :timestamp => Time::now.utc, :md5 => Digest::MD5::hexdigest(text_to_sign).to_s, :hits => 0 } log("Processing cache record: #{cache_key} => #{cache_record.inspect}") # Save current cache key for later use (by other Routines) data[:vars][:cache] ||= {} data[:vars][:cache][:key] = cache_key data[:vars][:cache][:record] = cache_record # Get the cache storage storage = (data[:vars][:system][:storage][:cache] ||= {} ) unless storage[cache_key] # Create a new record unless exists. storage[cache_key] = cache_record log("New cache record created") else # If the record is already there but the response changed the replace the old record. unless storage[cache_key][:md5] == cache_record[:md5] storage[cache_key] = cache_record log("Missed. Record is replaced") else # Raise if cache hits. storage[cache_key][:hits] += 1 = "Cache hit: #{cache_key.inspect} has not changed since " + "#{storage[cache_key][:timestamp].strftime('%Y-%m-%d %H:%M:%S')}, "+ "hits: #{storage[cache_key][:hits]}." log() fail CacheHit::new("CacheValidator: #{message}") end end break end true end |