Set custom stores #38

Closed
wants to merge 3 commits into
from
View
@@ -52,8 +52,8 @@ Storage Configuration
The MetaStore and EntityStore used for a particular request is determined by
inspecting the `rack-cache.metastore` and `rack-cache.entitystore` Rack env
-variables. The value of these variables is a URI that identifies the storage
-type and location (URI formats are documented in the following section).
+variables. The value of these variables is a URI or name that identifies the
+storage type and location (URI formats are documented in a following section).
The `heap:/` storage is assumed if either storage type is not explicitly
provided. This storage type has significant drawbacks for most types of
@@ -69,6 +69,37 @@ __Rack::Cache__ object is added to the Rack middleware pipeline as follows:
Alternatively, the `rack-cache.metastore` and `rack-cache.entitystore`
variables may be set in the Rack environment by an upstream component.
+Storage Registration
+--------------------
+
+If the needs for configuration your stores are more complex than the URIs allow,
+you may register a manually instantiated store. You can do this by calling the
+`register_metastore` and `register_entitystore` methods on the __Rack::Cache__
+instance when you set it up in your rack configuration.
+
+ use Rack::Cache do |rack_cache|
+ rack_cache.register_metastore, :my_metas,
+ ::Cache::MetaStore::Heap.new
+ rack_cache.register_entitystore, :my_entities,
+ ::Cache::EntityStore::Heap.new
+ rack_cache.use :metastore, :my_metas
+ rack_cache.use :entitystore, :my_entities
+ end
+
+You can also register storage instances directly on the`Rack::Cache::Storage.instance`
+singleton, and pass the name as the `:metastore` and `entitystore` values in the rack
+configuration:
+
+ Rack::Cache::Storage.instance.register_metastore :my_metas,
+ Rack::Cache::MetaStore::Heap.new
+ Rack::Cache::Storage.instance.register_entitystore :my_entities,
+ Rack::Cache::EntityStore::Heap.new
+
+ use Rack::Cache,
+ :metastore => :my_metas,
+ :entitystore => :my_entities
+
+
Storage Implementations
-----------------------
View
@@ -26,18 +26,28 @@ def initialize(backend, options={})
private_headers.map { |name| "HTTP_#{name.upcase.tr('-', '_')}" }
end
+ # Register a MetaStore instance. See Rack::Cache::Storage#register_metastore
+ def register_metastore(*args)
+ Storage.instance.register_metastore(*args)
+ end
+
# The configured MetaStore instance. Changing the rack-cache.metastore
# value effects the result of this method immediately.
def metastore
- uri = options['rack-cache.metastore']
- storage.resolve_metastore_uri(uri)
+ uri_or_name = options['rack-cache.metastore']
+ storage.resolve_metastore(uri_or_name)
+ end
+
+ # Register an EntityStore instance. See Rack::Cache::Storage#register_entitystore
+ def register_entitystore(*args)
+ Storage.instance.register_entitystore(*args)
end
# The configured EntityStore instance. Changing the rack-cache.entitystore
# value effects the result of this method immediately.
def entitystore
- uri = options['rack-cache.entitystore']
- storage.resolve_entitystore_uri(uri)
+ uri_or_name = options['rack-cache.entitystore']
+ storage.resolve_entitystore(uri_or_name)
end
# The Rack call interface. The receiver acts as a prototype and runs
View
@@ -14,13 +14,23 @@ def initialize
@entitystores = {}
end
- def resolve_metastore_uri(uri)
- @metastores[uri.to_s] ||= create_store(MetaStore, uri)
+ def register_metastore(name, storage_or_uri)
+ register_store(@metastores, MetaStore, name, storage_or_uri)
end
- def resolve_entitystore_uri(uri)
- @entitystores[uri.to_s] ||= create_store(EntityStore, uri)
+ def resolve_metastore(uri_or_name)
+ resolve_store(@metastores, MetaStore, uri_or_name)
end
+ alias_method :resolve_metastore_uri, :resolve_metastore
+
+ def register_entitystore(name, storage_or_uri)
+ register_store(@entitystores, EntityStore, name, storage_or_uri)
+ end
+
+ def resolve_entitystore(uri_or_name)
+ resolve_store(@entitystores, EntityStore, uri_or_name)
+ end
+ alias_method :resolve_entitystore_uri, :resolve_entitystore
def clear
@metastores.clear
@@ -52,6 +62,26 @@ def create_store(type, uri)
end
end
+ def register_store(stores_hash, type, name, storage_or_uri)
+ if stores_hash[name.to_s]
+ raise ArgumentError, "%s already registered: %s" % [type, name]
+ end
+
+ if storage_or_uri.is_a?(type)
+ stores_hash[name.to_s] = storage_or_uri
+ else
+ stores_hash[name.to_s] = create_store(type, storage_or_uri)
+ end
+ end
+
+ def resolve_store(stores_hash, type, uri_or_name)
+ if stores_hash[uri_or_name.to_s]
+ stores_hash[uri_or_name.to_s]
+ else
+ register_store(stores_hash, type, uri_or_name, create_store(type, uri_or_name))
+ end
+ end
+
public
@@singleton_instance = new
def self.instance
View
@@ -7,40 +7,50 @@
end
it "fails when an unknown URI scheme is provided" do
- lambda { @storage.resolve_metastore_uri('foo:/') }.should.raise
+ lambda { @storage.resolve_metastore('foo:/') }.should.raise
end
it "creates a new MetaStore for URI if none exists" do
- @storage.resolve_metastore_uri('heap:/').
+ @storage.resolve_metastore('heap:/').
should.be.kind_of Rack::Cache::MetaStore
end
it "returns an existing MetaStore instance for URI that exists" do
- store = @storage.resolve_metastore_uri('heap:/')
- @storage.resolve_metastore_uri('heap:/').should.be.same_as store
+ store = @storage.resolve_metastore('heap:/')
+ @storage.resolve_metastore('heap:/').should.be.same_as store
end
it "creates a new EntityStore for URI if none exists" do
- @storage.resolve_entitystore_uri('heap:/').
+ @storage.resolve_entitystore('heap:/').
should.be.kind_of Rack::Cache::EntityStore
end
it "returns an existing EntityStore instance for URI that exists" do
- store = @storage.resolve_entitystore_uri('heap:/')
- @storage.resolve_entitystore_uri('heap:/').should.be.same_as store
+ store = @storage.resolve_entitystore('heap:/')
+ @storage.resolve_entitystore('heap:/').should.be.same_as store
end
it "clears all URI -> store mappings with #clear" do
- meta = @storage.resolve_metastore_uri('heap:/')
- entity = @storage.resolve_entitystore_uri('heap:/')
+ meta = @storage.resolve_metastore('heap:/')
+ entity = @storage.resolve_entitystore('heap:/')
@storage.clear
- @storage.resolve_metastore_uri('heap:/').should.not.be.same_as meta
- @storage.resolve_entitystore_uri('heap:/').should.not.be.same_as entity
+ @storage.resolve_metastore('heap:/').should.not.be.same_as meta
+ @storage.resolve_entitystore('heap:/').should.not.be.same_as entity
+ end
+ it "registers a MetaStore by name" do
+ store = Rack::Cache::MetaStore::Heap.new
+ @storage.register_metastore(:foo, store)
+ @storage.resolve_metastore(:foo).should.be.same_as store
+ end
+ it "registers an EntityStore by name" do
+ store = Rack::Cache::EntityStore::Heap.new
+ @storage.register_entitystore(:foo, store)
+ @storage.resolve_entitystore(:foo).should.be.same_as store
end
describe 'Heap Store URIs' do
%w[heap:/ mem:/].each do |uri|
it "resolves #{uri} meta store URIs" do
- @storage.resolve_metastore_uri(uri).
+ @storage.resolve_metastore(uri).
should.be.kind_of Rack::Cache::MetaStore
end
it "resolves #{uri} entity store URIs" do
- @storage.resolve_entitystore_uri(uri).
+ @storage.resolve_entitystore(uri).
should.be.kind_of Rack::Cache::EntityStore
end
end
@@ -57,11 +67,11 @@
%w[file: disk:].each do |uri|
it "resolves #{uri} meta store URIs" do
- @storage.resolve_metastore_uri(uri + @temp_dir).
+ @storage.resolve_metastore(uri + @temp_dir).
should.be.kind_of Rack::Cache::MetaStore
end
it "resolves #{uri} entity store URIs" do
- @storage.resolve_entitystore_uri(uri + @temp_dir).
+ @storage.resolve_entitystore(uri + @temp_dir).
should.be.kind_of Rack::Cache::EntityStore
end
end
@@ -73,18 +83,18 @@
%w[memcache: memcached:].each do |scheme|
it "resolves #{scheme} meta store URIs" do
uri = scheme + '//' + ENV['MEMCACHED']
- @storage.resolve_metastore_uri(uri).
+ @storage.resolve_metastore(uri).
should.be.kind_of Rack::Cache::MetaStore
end
it "resolves #{scheme} entity store URIs" do
uri = scheme + '//' + ENV['MEMCACHED']
- @storage.resolve_entitystore_uri(uri).
+ @storage.resolve_entitystore(uri).
should.be.kind_of Rack::Cache::EntityStore
end
end
it 'supports namespaces in memcached: URIs' do
uri = "memcached://" + ENV['MEMCACHED'] + "/namespace"
- @storage.resolve_metastore_uri(uri).
+ @storage.resolve_metastore(uri).
should.be.kind_of Rack::Cache::MetaStore
end
end