Class: Horcrux::Multiple
- Inherits:
-
Object
- Object
- Horcrux::Multiple
- Includes:
- Methods
- Defined in:
- lib/horcrux/multiple.rb
Instance Attribute Summary collapse
-
#error_handlers ⇒ Object
readonly
Returns the value of attribute error_handlers.
-
#missing_handlers ⇒ Object
readonly
Returns the value of attribute missing_handlers.
-
#rescuable_exceptions ⇒ Object
readonly
Returns the value of attribute rescuable_exceptions.
Instance Method Summary collapse
-
#call_adapter(adapter, method, *args) ⇒ Object
Calls the given adapter, swallowing up any error.
-
#call_missing_handlers(values, missing) ⇒ Object
Call the on_missing callbacks for the handlers that were missing keys.
- #delete(key) ⇒ Object
- #delete_all(*keys) ⇒ Object
- #get(key) ⇒ Object
-
#get_all(*keys) ⇒ Object
HORCRUX METHODS.
-
#get_from_adapter(adapter, keys) ⇒ Object
Gets all keys from the adapter.
-
#initialize(*adapters) ⇒ Multiple
constructor
Sets up an Adapter using a collection of other adapters.
- #key?(key) ⇒ Boolean
-
#on_error(&block) ⇒ Object
Public: Adds the given block to the chain of handlers to call for a raised exception while accessing one of the adapters.
-
#on_missing(&block) ⇒ Object
Public: Adds the given block to the chain of handlers to call when a secondary adapter is missing one or more keys.
-
#read_cache(method, *args) ⇒ Object
Reads the data from the other adapters before the main adapter.
- #set(key, value) ⇒ Object
- #set_all(values) ⇒ Object
-
#write_through(method, *args) ⇒ Object
Writes the data to the main adapter first, and then to the other adapters.
Methods included from Methods
Constructor Details
#initialize(*adapters) ⇒ Multiple
Sets up an Adapter using a collection of other adapters. The first is assumed to be the main, while the others are write-through caches. This is good for caching.
mysql = Horcrux::MysqlAdapter.new ... # fake
memcache = Horcrux::MemcacheAdapter.new ... # fake
adapter = Horcrux::Multiple.new mysql, memcache
Reads will hit the secondary adapters before the main. Writes will hit the main adapter first, before being sent to the secondary adapters.
*adapters - One or more Horcrux-compliant adapters.
20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/horcrux/multiple.rb', line 20 def initialize(*adapters) if adapters.empty? raise ArgumentError, "Need at least 1 adapter." end @main = adapters.shift @adapters = adapters @error_handlers = [] @missing_handlers = [] @rescuable_exceptions = [StandardError] end |
Instance Attribute Details
#error_handlers ⇒ Object (readonly)
Returns the value of attribute error_handlers.
6 7 8 |
# File 'lib/horcrux/multiple.rb', line 6 def error_handlers @error_handlers end |
#missing_handlers ⇒ Object (readonly)
Returns the value of attribute missing_handlers.
6 7 8 |
# File 'lib/horcrux/multiple.rb', line 6 def missing_handlers @missing_handlers end |
#rescuable_exceptions ⇒ Object (readonly)
Returns the value of attribute rescuable_exceptions.
5 6 7 |
# File 'lib/horcrux/multiple.rb', line 5 def rescuable_exceptions @rescuable_exceptions end |
Instance Method Details
#call_adapter(adapter, method, *args) ⇒ Object
Calls the given adapter, swallowing up any error.
adapter - A Horcrux adapter. method - A Symbol identifying the method to call. *args - One or more arguments to send to the methods.
Returns the value of the method call.
148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/horcrux/multiple.rb', line 148 def call_adapter(adapter, method, *args) adapter.send(method, *args) rescue Object => err raise unless @rescuable_exceptions.any? { |klass| err.is_a?(klass) } if @error_handlers.each do |handler| handler.call err, :adapter => adapter, :method => method, :args => args end.empty? $stderr.puts "#{err.class} Exception for #{adapter.inspect}##{method}: #{err}" end end |
#call_missing_handlers(values, missing) ⇒ Object
Call the on_missing callbacks for the handlers that were missing keys. This gives you a chance to set those values in the secondary adapters.
values - A Hash of all of the found keys => values. missing - A Hash of Adapter => Array of missing keys.
Returns nothing.
191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/horcrux/multiple.rb', line 191 def call_missing_handlers(values, missing) return if @missing_handlers.empty? missing.each do |adapter, keys| missing_values = {} keys.each do |key| missing_values[key] = values[key] end @missing_handlers.each do |handler| handler.call adapter, missing_values end end end |
#delete(key) ⇒ Object
102 103 104 |
# File 'lib/horcrux/multiple.rb', line 102 def delete(key) write_through :delete, key end |
#delete_all(*keys) ⇒ Object
106 107 108 |
# File 'lib/horcrux/multiple.rb', line 106 def delete_all(*keys) write_through :delete_all, *keys end |
#get(key) ⇒ Object
90 91 92 |
# File 'lib/horcrux/multiple.rb', line 90 def get(key) read_cache :get, key end |
#get_all(*keys) ⇒ Object
HORCRUX METHODS
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/horcrux/multiple.rb', line 62 def get_all(*keys) original = keys.dup adapter_missing = {} values = {} @adapters.each do |adapter| found, missing = get_from_adapter(adapter, keys) values.update(found) if !missing.empty? adapter_missing[adapter] = missing end keys = missing end found, missing = get_from_adapter(@main, keys) values.update(found) call_missing_handlers(values, adapter_missing) original.map { |key| values[key] } end |
#get_from_adapter(adapter, keys) ⇒ Object
Gets all keys from the adapter.
adapter - A Horcrux adapter. keys - Array of String keys to fetch.
Returns an Array tuple with a Hash of found keys/values, and an Array of missing keys.
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/horcrux/multiple.rb', line 167 def get_from_adapter(adapter, keys) missing = [] found = {} adapter.get_all(*keys).each_with_index do |value, index| key = keys[index] if value found[key] = value else missing << key end end unless keys.empty? [found, missing] end |
#key?(key) ⇒ Boolean
86 87 88 |
# File 'lib/horcrux/multiple.rb', line 86 def key?(key) read_cache :key?, key end |
#on_error(&block) ⇒ Object
Public: Adds the given block to the chain of handlers to call for a raised exception while accessing one of the adapters.
@adapter.on_error do |err, obj|
obj[:adapter]
obj[:method]
obj[:args]
end
Returns nothing.
42 43 44 45 |
# File 'lib/horcrux/multiple.rb', line 42 def on_error(&block) @error_handlers << block nil end |
#on_missing(&block) ⇒ Object
Public: Adds the given block to the chain of handlers to call when a secondary adapter is missing one or more keys.
@adapter.on_missing do |adapter, values|
adapter.set_all(values)
end
Returns nothing.
55 56 57 58 |
# File 'lib/horcrux/multiple.rb', line 55 def on_missing(&block) @missing_handlers << block nil end |
#read_cache(method, *args) ⇒ Object
Reads the data from the other adapters before the main adapter.
method - A Symbol identifying the method to call. *args - One or more arguments to send to the methods.
Returns the result of the first adapter to respond with a value.
133 134 135 136 137 138 139 |
# File 'lib/horcrux/multiple.rb', line 133 def read_cache(method, *args) value = nil @adapters.detect do |adapter| value = call_adapter adapter, method, *args end value || @main.send(method, *args) end |
#set(key, value) ⇒ Object
94 95 96 |
# File 'lib/horcrux/multiple.rb', line 94 def set(key, value) write_through :set, key, value end |
#set_all(values) ⇒ Object
98 99 100 |
# File 'lib/horcrux/multiple.rb', line 98 def set_all(values) write_through :set_all, values end |
#write_through(method, *args) ⇒ Object
Writes the data to the main adapter first, and then to the other adapters.
method - A Symbol identifying the method to call. *args - One or more arguments to send to the methods.
Returns the result of the method call on the main adapter.
119 120 121 122 123 124 125 |
# File 'lib/horcrux/multiple.rb', line 119 def write_through(method, *args) result = @main.send(method, *args) @adapters.each do |adapter| call_adapter adapter, method, *args end result end |