Module: SafeMemoize
- Includes:
- InstanceMethods
- Defined in:
- lib/safe_memoize.rb,
lib/safe_memoize/rails.rb,
lib/safe_memoize/version.rb,
lib/safe_memoize/extension.rb,
lib/safe_memoize/lru_methods.rb,
lib/safe_memoize/stores/base.rb,
lib/safe_memoize/stores/redis.rb,
lib/safe_memoize/class_methods.rb,
lib/safe_memoize/configuration.rb,
lib/safe_memoize/hooks_methods.rb,
lib/safe_memoize/stores/memory.rb,
lib/safe_memoize/public_methods.rb,
lib/safe_memoize/adapters/statsd.rb,
lib/safe_memoize/release_tooling.rb,
lib/safe_memoize/instance_methods.rb,
lib/safe_memoize/rails/middleware.rb,
lib/safe_memoize/custom_key_methods.rb,
lib/safe_memoize/inspection_methods.rb,
lib/safe_memoize/stores/rails_cache.rb,
lib/safe_memoize/cache_store_methods.rb,
lib/safe_memoize/fiber_local_methods.rb,
lib/safe_memoize/cache_record_methods.rb,
lib/safe_memoize/rails/request_scoped.rb,
lib/safe_memoize/cache_metrics_methods.rb,
lib/safe_memoize/ractor_shared_methods.rb,
lib/safe_memoize/adapters/opentelemetry.rb,
lib/safe_memoize/public_metrics_methods.rb,
lib/safe_memoize/stores/circuit_breaker.rb,
lib/safe_memoize/adapters/concurrent_ruby.rb,
lib/safe_memoize/public_custom_key_methods.rb
Overview
Thread-safe memoization for Ruby that correctly handles +nil+ and +false+ values.
Prepend this module into any class, then call ClassMethods#memoize to wrap instance methods with a per-instance cache backed by a +Mutex+.
Defined Under Namespace
Modules: Adapters, CacheMetricsMethods, CacheRecordMethods, CacheStoreMethods, ClassMethods, CustomKeyMethods, Extension, FiberLocalMethods, HooksMethods, InspectionMethods, InstanceMethods, LruMethods, PublicCustomKeyMethods, PublicMethods, PublicMetricsMethods, RactorSharedMethods, Rails, ReleaseTooling, Stores Classes: Configuration, Error
Constant Summary collapse
- UNSET =
Object.new.freeze
- SHARED_CACHE_REGISTRY =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
{}
- SHARED_CACHE_MUTEX =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Mutex.new
- EXTENSION_REGISTRY =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
{}
- EXTENSION_MUTEX =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Mutex.new
- VERSION =
The current gem version string.
"1.6.0"
Constants included from FiberLocalMethods
FiberLocalMethods::FIBER_STORE_KEY
Constants included from HooksMethods
HooksMethods::NOTIFICATION_EVENT_NAMES
Class Method Summary collapse
-
.clear_shared_cache(name) ⇒ void
Clears all entries in the named shared cache without removing it from the registry.
-
.configuration ⇒ Configuration
Returns the global Configuration instance, creating it on first access.
-
.configure {|config| ... } ⇒ void
Yields the global Configuration object for mutation.
-
.deprecate(subject, message:, horizon:) ⇒ void
Emits a structured deprecation warning through the configured handler.
-
.dispatch_extension_events(event_type, klass, method_name, cache_key, record) ⇒ Object
private
Dispatches a cache lifecycle event to all registered extensions that respond to +dispatch_cache_event+.
-
.drop_shared_cache(name) ⇒ Stores::Base?
Removes the named shared cache from the registry entirely.
-
.extension_for_option(option_name) ⇒ Object?
Returns the first registered extension that declares it handles +option_name+, or +nil+ if none does.
-
.extensions ⇒ Hash{Symbol => Object}
Returns a snapshot of all registered extensions as a +Hash+.
- .prepended(base) ⇒ Object private
-
.register_extension(name, extension) ⇒ Object
Registers an extension under +name+.
-
.register_shared_cache(name, store) ⇒ Stores::Base
Registers a custom store under +name+, replacing any existing entry.
-
.reset_configuration! ⇒ Configuration
Resets the global configuration to all defaults.
-
.reset_extensions! ⇒ void
Removes all registered extensions.
-
.reset_shared_caches! ⇒ void
Removes all named shared caches from the registry.
-
.shared_cache(name) ⇒ Stores::Base
Returns the named shared cache store, creating a new in-process Stores::Memory instance if one has not been registered under +name+.
-
.shared_caches ⇒ Hash{String => Stores::Base}
Returns a snapshot of the current registry as a plain +Hash+.
-
.unregister_extension(name) ⇒ Object?
Removes an extension from the registry.
Methods included from FiberLocalMethods
#fiber_local_memoized?, #reset_all_fiber_memos, #reset_fiber_memo
Methods included from PublicCustomKeyMethods
#clear_custom_keys, #memoize_with_custom_key
Methods included from PublicMetricsMethods
#cache_hit_rate, #cache_metrics_reset, #cache_miss_rate, #cache_stats, #cache_stats_for
Methods included from PublicMethods
#clear_memo_hooks, #dump_memo, #load_memo, #memo_age, #memo_count, #memo_group_methods, #memo_groups, #memo_inspect, #memo_keys, #memo_preload, #memo_refresh, #memo_stale?, #memo_touch, #memo_ttl_remaining, #memo_values, #memoized?, #on_memo_evict, #on_memo_expire, #on_memo_hit, #on_memo_miss, #on_memo_store, #reset_all_memos, #reset_memo, #reset_memo_group, #warm_memo
Class Method Details
.clear_shared_cache(name) ⇒ void
This method returns an undefined value.
Clears all entries in the named shared cache without removing it from the registry. A no-op when no cache is registered under +name+.
156 157 158 |
# File 'lib/safe_memoize.rb', line 156 def self.clear_shared_cache(name) SHARED_CACHE_MUTEX.synchronize { SHARED_CACHE_REGISTRY[name]&.clear } end |
.configuration ⇒ Configuration
Returns the global Configuration instance, creating it on first access.
96 97 98 |
# File 'lib/safe_memoize.rb', line 96 def self.configuration @configuration ||= Configuration.new end |
.configure {|config| ... } ⇒ void
This method returns an undefined value.
Yields the global Configuration object for mutation.
89 90 91 |
# File 'lib/safe_memoize.rb', line 89 def self.configure yield configuration end |
.deprecate(subject, message:, horizon:) ⇒ void
This method returns an undefined value.
Emits a structured deprecation warning through the configured handler.
115 116 117 118 119 |
# File 'lib/safe_memoize.rb', line 115 def self.deprecate(subject, message:, horizon:) text = "[SafeMemoize] #{subject} is deprecated and will be removed in #{horizon}. #{}" handler = configuration.on_deprecation handler ? handler.call(text) : warn(text) end |
.dispatch_extension_events(event_type, klass, method_name, cache_key, record) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Dispatches a cache lifecycle event to all registered extensions that respond to +dispatch_cache_event+.
241 242 243 244 245 246 |
# File 'lib/safe_memoize.rb', line 241 def self.dispatch_extension_events(event_type, klass, method_name, cache_key, record) exts = EXTENSION_MUTEX.synchronize { EXTENSION_REGISTRY.values.dup } exts.each do |ext| ext.dispatch_cache_event(event_type, klass, method_name, cache_key, record) if ext.respond_to?(:dispatch_cache_event) end end |
.drop_shared_cache(name) ⇒ Stores::Base?
Removes the named shared cache from the registry entirely. Subsequent +shared_cache(name)+ calls will create a fresh store.
165 166 167 |
# File 'lib/safe_memoize.rb', line 165 def self.drop_shared_cache(name) SHARED_CACHE_MUTEX.synchronize { SHARED_CACHE_REGISTRY.delete(name) } end |
.extension_for_option(option_name) ⇒ Object?
Returns the first registered extension that declares it handles +option_name+, or +nil+ if none does.
228 229 230 231 232 233 234 235 |
# File 'lib/safe_memoize.rb', line 228 def self.extension_for_option(option_name) sym = option_name.to_sym EXTENSION_MUTEX.synchronize do EXTENSION_REGISTRY.values.find do |ext| ext.respond_to?(:handled_options) && ext..include?(sym) end end end |
.extensions ⇒ Hash{Symbol => Object}
Returns a snapshot of all registered extensions as a +Hash+.
210 211 212 |
# File 'lib/safe_memoize.rb', line 210 def self.extensions EXTENSION_MUTEX.synchronize { EXTENSION_REGISTRY.dup } end |
.prepended(base) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
75 76 77 |
# File 'lib/safe_memoize.rb', line 75 def self.prepended(base) base.extend(ClassMethods) end |
.register_extension(name, extension) ⇒ Object
Registers an extension under +name+.
An extension is any Ruby object that optionally responds to the Extension interface: SafeMemoize::Extension#handled_options, SafeMemoize::Extension#process_memoize_option, and SafeMemoize::Extension#dispatch_cache_event. Use Extension as a mixin to get a convenient DSL for defining these.
195 196 197 |
# File 'lib/safe_memoize.rb', line 195 def self.register_extension(name, extension) EXTENSION_MUTEX.synchronize { EXTENSION_REGISTRY[name.to_sym] = extension } end |
.register_shared_cache(name, store) ⇒ Stores::Base
Registers a custom store under +name+, replacing any existing entry.
Must be called before any class that references +name+ via +shared_cache:+ is loaded, because the store is captured at +memoize+ definition time.
144 145 146 147 148 149 |
# File 'lib/safe_memoize.rb', line 144 def self.register_shared_cache(name, store) unless store.is_a?(Stores::Base) raise ArgumentError, "store must be a SafeMemoize::Stores::Base instance (got #{store.class})" end SHARED_CACHE_MUTEX.synchronize { SHARED_CACHE_REGISTRY[name] = store } end |
.reset_configuration! ⇒ Configuration
Resets the global configuration to all defaults.
Useful in test suites to prevent configuration leaking between examples.
105 106 107 |
# File 'lib/safe_memoize.rb', line 105 def self.reset_configuration! @configuration = Configuration.new end |
.reset_extensions! ⇒ void
This method returns an undefined value.
Removes all registered extensions.
Useful in test suite +after+ hooks to prevent state leaking between examples.
219 220 221 |
# File 'lib/safe_memoize.rb', line 219 def self.reset_extensions! EXTENSION_MUTEX.synchronize { EXTENSION_REGISTRY.clear } end |
.reset_shared_caches! ⇒ void
This method returns an undefined value.
Removes all named shared caches from the registry.
Useful in test suite +after+ hooks to prevent state leaking between examples.
181 182 183 |
# File 'lib/safe_memoize.rb', line 181 def self.reset_shared_caches! SHARED_CACHE_MUTEX.synchronize { SHARED_CACHE_REGISTRY.clear } end |
.shared_cache(name) ⇒ Stores::Base
Returns the named shared cache store, creating a new in-process SafeMemoize::Stores::Memory instance if one has not been registered under +name+.
Use register_shared_cache to supply a custom adapter (e.g. Redis) before any class that references the same name is loaded.
129 130 131 132 133 |
# File 'lib/safe_memoize.rb', line 129 def self.shared_cache(name) SHARED_CACHE_MUTEX.synchronize do SHARED_CACHE_REGISTRY[name] ||= Stores::Memory.new end end |
.shared_caches ⇒ Hash{String => Stores::Base}
Returns a snapshot of the current registry as a plain +Hash+.
172 173 174 |
# File 'lib/safe_memoize.rb', line 172 def self.shared_caches SHARED_CACHE_MUTEX.synchronize { SHARED_CACHE_REGISTRY.dup } end |
.unregister_extension(name) ⇒ Object?
Removes an extension from the registry.
203 204 205 |
# File 'lib/safe_memoize.rb', line 203 def self.unregister_extension(name) EXTENSION_MUTEX.synchronize { EXTENSION_REGISTRY.delete(name.to_sym) } end |