Class: ActiveSupport::Cache::CouchbaseStore
- Inherits:
-
Store
- Object
- Store
- ActiveSupport::Cache::CouchbaseStore
- Includes:
- Strategy::LocalCache
- Defined in:
- lib/active_support/cache/couchbase_store.rb
Overview
A cache store implementation which stores data in Couchbase: couchbase.com
-
Local cache. Hot in-memory primary cache within block/middleware scope.
-
read_multi
andwrite_multi
support. -
delete_matched
support using N1QL queries. -
clear
for erasing whole collection (optionally can flush the bucket).
To use this store, add the select it in application config
config.cache_store = :couchbase_store, {
connection_string: "couchbase://localhost",
username: "app_cache_user",
password: "s3cret",
bucket: "app_cache"
}
Constant Summary collapse
- MAX_KEY_BYTESIZE =
250
- DEFAULT_ERROR_HANDLER =
lambda do |method:, returning:, exception:, logger: CouchbaseStore.logger| logger&.error { "CouchbaseStore: #{method} failed, returned #{returning.inspect}: #{exception.class}: #{exception.}" } end
Class Method Summary collapse
-
.supports_cache_versioning? ⇒ Boolean
Advertise cache versioning support.
Instance Method Summary collapse
-
#clear(use_flush: false, **_options) ⇒ Object
Clears the entire cache.
- #cluster ⇒ Object
- #collection ⇒ Object
-
#decrement(name, amount = 1, expires_in: nil, initial: nil, **_options) ⇒ Object
Decrements an integer value in the cache.
-
#delete_matched(matcher, _options = nil) ⇒ Object
Deletes all entries with keys matching the regular expression.
-
#increment(name, amount = 1, expires_in: nil, initial: nil, **options) ⇒ Object
Increments an integer value in the cache.
-
#initialize(options = nil) ⇒ CouchbaseStore
constructor
A new instance of CouchbaseStore.
- #inspect ⇒ Object
Constructor Details
#initialize(options = nil) ⇒ CouchbaseStore
Returns a new instance of CouchbaseStore.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/active_support/cache/couchbase_store.rb', line 53 def initialize( = nil) super @error_handler = @options.delete(:error_handler) { DEFAULT_ERROR_HANDLER } @couchbase_options = {} @couchbase_options[:connection_string] = @options.delete(:connection_string) do raise ArgumentError, "Missing connection string for Couchbase cache store. Use :connection_string in the store options" end @couchbase_options[:username] = @options.delete(:username) do raise ArgumentError, "Missing username for Couchbase cache store. Use :username in the store options" end @couchbase_options[:password] = @options.delete(:password) do raise ArgumentError, "Missing password for Couchbase cache store. Use :password in the store options" end @couchbase_options[:bucket] = @options.delete(:bucket) { raise ArgumentError, "Missing bucket for Couchbase cache store. Use :bucket in the store options" } @couchbase_options[:scope] = @options.delete(:scope) if @options.key?(:scope) @couchbase_options[:collection] = @options.delete(:collection) if @options.key?(:collection) @last_mutation_token = nil end |
Class Method Details
.supports_cache_versioning? ⇒ Boolean
Advertise cache versioning support.
47 48 49 |
# File 'lib/active_support/cache/couchbase_store.rb', line 47 def self.supports_cache_versioning? true end |
Instance Method Details
#clear(use_flush: false, **_options) ⇒ Object
Clears the entire cache. Be careful with this method since it could affect other processes if shared cache is being used.
When use_flush
option set to true
it will flush the bucket. Otherwise, it uses N1QL query and relies on default index.
161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/active_support/cache/couchbase_store.rb', line 161 def clear(use_flush: false, **) failsafe(:clear) do if use_flush cluster.buckets.flush_bucket(@couchbase_options[:bucket_name]) else = ::Couchbase::Options::Query.new .consistent_with(::Couchbase::MutationState.new(@last_mutation_token)) if @last_mutation_token cluster.query("DELETE FROM #{scope_qualifier}", ) end end end |
#cluster ⇒ Object
80 81 82 |
# File 'lib/active_support/cache/couchbase_store.rb', line 80 def cluster @cluster ||= build_cluster end |
#collection ⇒ Object
76 77 78 |
# File 'lib/active_support/cache/couchbase_store.rb', line 76 def collection @collection ||= build_collection end |
#decrement(name, amount = 1, expires_in: nil, initial: nil, **_options) ⇒ Object
Decrements an integer value in the cache.
Note that it uses binary collection interface, therefore will fail if the value is not represented as ASCII-encoded number using :raw
.
Note that the counter represented by non-negative number on the server, and it will not cycle to maximum integer when decrementing zero.
143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/active_support/cache/couchbase_store.rb', line 143 def decrement(name, amount = 1, expires_in: nil, initial: nil, **) instrument :decrement, name, amount: amount do failsafe :decrement do key = normalize_key(name, ) res = collection.binary.decrement( key, ::Couchbase::Options::Decrement(delta: amount, expiry: expires_in, initial: initial) ) @last_mutation_token = res.mutation_token res.content end end end |
#delete_matched(matcher, _options = nil) ⇒ Object
Deletes all entries with keys matching the regular expression.
The matcher
must be valid pattern for N1QL REGEXP_MATCHES
function. More info at docs.couchbase.com/server/current/n1ql/n1ql-language-reference/patternmatchingfun.html#section_regex_matches
Because the operation performed on query engine, and it might take time to propagate changes from key/value engine to the indexer. Therefore the keys, that were created a moment ago might not be deleted.
Also this method assumes, that primary index created on the target bucket
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/active_support/cache/couchbase_store.rb', line 98 def delete_matched(matcher, = nil) pattern = case matcher when Regexp matcher.inspect[1..-2] when String matcher.tr("?", ".").gsub("*", ".*") else raise NotImplementedError, "Unable to convert #{matcher.inspect} to Regexp pattern" end = ::Couchbase::Options::Query(named_parameters: {"pattern" => pattern}, metrics: true) .consistent_with(::Couchbase::MutationState.new(@last_mutation_token)) if @last_mutation_token begin result = cluster.query("DELETE FROM #{scope_qualifier} cache_store_ WHERE REGEXP_MATCHES(META(cache_store_).id, $pattern)", ) result..metrics.mutation_count rescue ::Couchbase::Error::ParsingFailure, ::Couchbase::Error::ServiceNotAvailable raise NotImplementedError, "The server does not support delete_matched operation" end end |
#increment(name, amount = 1, expires_in: nil, initial: nil, **options) ⇒ Object
Increments an integer value in the cache.
Note that it uses binary collection interface, therefore will fail if the value is not represented as ASCII-encoded number using :raw
.
123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/active_support/cache/couchbase_store.rb', line 123 def increment(name, amount = 1, expires_in: nil, initial: nil, **) instrument :increment, name, amount: amount do failsafe :increment do key = normalize_key(name, ) res = collection.binary.increment( key, ::Couchbase::Options::Increment(delta: amount, expiry: expires_in, initial: initial) ) @last_mutation_token = res.mutation_token res.content end end end |
#inspect ⇒ Object
84 85 86 |
# File 'lib/active_support/cache/couchbase_store.rb', line 84 def inspect "#<#{self.class} options=#{.inspect} collection=#{@collection.inspect}>" end |