Class: Stockpile
Overview
Stockpile is a thin wrapper around connections to a fast key-value store used for caching (currently only supporting Redis).
This provides a couple of layers of functionality:
-
Connection management. Some third-party providers of Redis limit simultaneous connections; Stockpile can manage a single connection that gets shared by all clients using a Stockpile instance.
-
Providing an application-level cache adapter mechanism.
Constant Summary collapse
- VERSION =
:nodoc:
"1.0"
Class Attribute Summary collapse
-
.default_manager ⇒ Object
The default Stockpile cache connection manager.
Class Method Summary collapse
-
.inject!(mod, options = {}) ⇒ Object
Enables module or class
mod
to contain a Stockpile instance and provide an adapter interface (this can be disabled). -
.narrow? ⇒ Boolean
Determines if the default connection width is narrow or wide based on the environment variable STOCKPILE_CONNECTION_WIDTH.
Instance Method Summary collapse
-
#initialize(options = {}) {|_self| ... } ⇒ Stockpile
constructor
Creates a new Stockpile instance and connects to the connection provider using the provided options and block.
Constructor Details
#initialize(options = {}) {|_self| ... } ⇒ Stockpile
Creates a new Stockpile instance and connects to the connection provider using the provided options and block.
Options
The options hash contains configuration for the Stockpile and its connection manager. The following options are handled specially by the Stockpile constructor and not made available to the connection provider constructor.
manager
-
The connection manager that will be used for creating connections to this Stockpile. If not provided, either
default_manager
or ::Stockpile.default_manager will be used. An error will be raised if no connection provider is available through any means. clients
-
Connections will be created for the provided list of clients. These connections must be assigned to their appropriate clients after initialization. This may also be called
client
.
All other options will be passed to the connection provider.
Synopsis
# Create and assign a connection to Redis.current, Resque, and Rollout.
# Under a narrow connection management width, all three will be the
# same client connection.
Stockpile.new(manager: Stockpile::Redis, clients: [ :redis, :resque ]) do |stockpile|
Redis.current = stockpile.connection_for(:redis)
Resque.redis = stockpile.connection_for(:resque)
# Clients will be created by name if necessary.
$rollout = Rollout.new(stockpile.connection_for(:rollout))
end
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/stockpile.rb', line 149 def initialize( = {}) manager = .fetch(:manager) { [:default_manager] || self.class.default_manager } unless manager raise ArgumentError, "No connection manager provided or set as default." end clients = (Array([:clients]) + Array([:client])).flatten.uniq = { narrow: Stockpile.narrow? }.merge(.reject { |k, _| k == :manager || k == :clients || k == :client }) @manager = manager.new() connect(*clients) yield self if block_given? end |
Class Attribute Details
.default_manager ⇒ Object
The default Stockpile cache connection manager.
114 115 116 |
# File 'lib/stockpile.rb', line 114 def default_manager @default_manager end |
Class Method Details
.inject!(mod, options = {}) ⇒ Object
Enables module or class mod
to contain a Stockpile instance and provide an adapter interface (this can be disabled). This creates a singleton method that returns a singleton Stockpile instance.
Options
method
-
The name of the method that manages the Stockpile instance. Defaults to
cache
. adaptable
-
Defines an adapter method if truthy (the default). Pass a falsy value to disable. (The created adapter method will be named according to the value of
method
, and so defaults tocache_adapter
.
Synopsis
# Using only for connection management.
module Application
Stockpile.inject!(self, adaptable: false)
end
Application.cache # => a stockpile instance
Application.cache.connection.set('answer', 42)
Application.cache.connection.get('answer')
module LastRunTime
def last_run_time(key, value = nil)
if value
connection.hset(__method__, key, value.utc.iso8601)
else
value = connection.hget(__method__, key)
Time.parse(value) if value
end
end
end
module AdaptableApplication; end
Stockpile.inject!(AdaptableApplication)
# Adapt the cache object to recognize #last_run_time;
AdaptableApplication.cache_adapter(LastRunTime)
AdaptableApplication.cache.last_run_time('adaptable_application')
# or adapt AdaptableApplication to recognize #last_run_time;
AdaptableApplication.cache_adapter(LastRunTime,
AdaptableApplication)
AdaptableApplication.last_run_time('adaptable_application')
# or adapt LastRunTime to recognize #last_run_time.
AdaptableApplication.cache_adapter!(LastRunTime)
LastRunTime.last_run_time('adaptable_application')
76 77 78 79 80 81 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 |
# File 'lib/stockpile.rb', line 76 def inject!(mod, = {}) unless mod.kind_of?(Module) raise ArgumentError, "#{mod} is not a class or module" end name = .fetch(:method, :cache).to_sym msc = mod.singleton_class default = .fetch(:default_manager, nil) msc.send(:define_method, name) do | = {}| = .merge(default_manager: default) @__stockpile__ ||= ::Stockpile.new() end if .fetch(:adaptable, true) adapter = :"#{name}_adapter" msc.send(:define_method, adapter) do |m, k = nil| o = self send(name).singleton_class.send(:include, m) if k mk = k.singleton_class m.public_instance_methods.each do |pim| mk.send(:define_method, pim) do |*args, &block| o.send(name).send(pim, *args, &block) end end end end msc.send(:define_method, :"#{adapter}!") do |m| send(adapter, m, m) end end end |
.narrow? ⇒ Boolean
Determines if the default connection width is narrow or wide based on the environment variable STOCKPILE_CONNECTION_WIDTH.
24 25 26 |
# File 'lib/stockpile.rb', line 24 def narrow? (ENV['STOCKPILE_CONNECTION_WIDTH'] == 'narrow') end |