Class: ActiveSupport::Cache::CouchbaseStore
- Inherits:
-
Store
- Object
- Store
- ActiveSupport::Cache::CouchbaseStore
- Includes:
- Strategy::LocalCache
- Defined in:
- lib/active_support/cache/couchbase_store.rb,
/home/runner/work/couchbase-ruby-client/couchbase-ruby-client/lib/active_support/cache/couchbase_store.rb
Overview
A cache store implementation which stores data in Couchbase: https://couchbase.com
- Local cache. Hot in-memory primary cache within block/middleware scope.
read_multiandwrite_multisupport.delete_matchedsupport using N1QL queries.clearfor 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"
}
delete_matched and clear query with consistent_with the store's writes.
By default that covers the last write only, which leaves earlier writes to
other vBuckets out of the query until the index catches up. With
mutation_tracking: :all the store keeps the newest mutation token of every
vBucket it wrote to, so both see every earlier write. It also accepts an
object that responds to record(*tokens) and mutation_state.
Defined Under Namespace
Classes: AllMutations, LastMutation
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.
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 |
# File 'lib/active_support/cache/couchbase_store.rb', line 105 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) @mutations = case (tracking = @options.delete(:mutation_tracking) { :last }) when :last, "last" then LastMutation.new when :all, "all" then AllMutations.new else unless tracking.respond_to?(:record) && tracking.respond_to?(:mutation_state) raise ArgumentError, "mutation_tracking must be :last, :all, or respond to #record and #mutation_state" end tracking end end |
Class Method Details
.supports_cache_versioning? ⇒ Boolean
Advertise cache versioning support.
99 100 101 |
# File 'lib/active_support/cache/couchbase_store.rb', line 99 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.
225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/active_support/cache/couchbase_store.rb', line 225 def clear(use_flush: false, **) failsafe(:clear) do if use_flush cluster.buckets.flush_bucket(@couchbase_options[:bucket_name]) else = ::Couchbase::Options::Query.new mutation_state = @mutations.mutation_state .consistent_with(mutation_state) if mutation_state cluster.query("DELETE FROM #{scope_qualifier}", ) end end end |
#cluster ⇒ Object
142 143 144 |
# File 'lib/active_support/cache/couchbase_store.rb', line 142 def cluster @cluster ||= build_cluster end |
#collection ⇒ Object
138 139 140 |
# File 'lib/active_support/cache/couchbase_store.rb', line 138 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.
207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/active_support/cache/couchbase_store.rb', line 207 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) ) @mutations.record(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
https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/patternmatchingfun.html#section_regex_matches
The query is consistent with the writes this store recorded, as selected by
mutation_tracking. With the default :last, keys written shortly before the
last write to other vBuckets might not be deleted. Writes by other processes
are not covered.
Also this method assumes, that primary index created on the target bucket
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/active_support/cache/couchbase_store.rb', line 161 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) mutation_state = @mutations.mutation_state .consistent_with(mutation_state) if mutation_state 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.
187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/active_support/cache/couchbase_store.rb', line 187 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) ) @mutations.record(res.mutation_token) res.content end end end |
#inspect ⇒ Object
146 147 148 |
# File 'lib/active_support/cache/couchbase_store.rb', line 146 def inspect "#<#{self.class} options=#{.inspect} collection=#{@collection.inspect}>" end |