Class: Magick::Config
- Inherits:
-
Object
- Object
- Magick::Config
- Defined in:
- lib/magick/config.rb
Instance Attribute Summary collapse
-
#active_record_model_class ⇒ Object
Returns the value of attribute active_record_model_class.
-
#adapter_registry ⇒ Object
Returns the value of attribute adapter_registry.
-
#async_enqueue_timeout ⇒ Object
Returns the value of attribute async_enqueue_timeout.
-
#async_queue_limit ⇒ Object
Returns the value of attribute async_queue_limit.
-
#async_updates(enabled: true, queue_limit: nil, enqueue_timeout: nil) ⇒ Object
Asynchronous Redis writes.
-
#audit_log(enabled: true, adapter: nil, retention: AuditLog::DEFAULT_RETENTION, max_entries: AuditLog::DEFAULT_MAX_ENTRIES, persist: true) ⇒ Object
enabled: false disables audit logging entirely (Magick.audit_log is nil).
-
#circuit_breaker_threshold ⇒ Object
Returns the value of attribute circuit_breaker_threshold.
-
#circuit_breaker_timeout ⇒ Object
Returns the value of attribute circuit_breaker_timeout.
-
#environment(name) ⇒ Object
Returns the value of attribute environment.
-
#memory_ttl(seconds) ⇒ Object
Returns the value of attribute memory_ttl.
-
#performance_metrics(enabled: true, redis_tracking: nil, batch_size: 100, flush_interval: 60, **_options) ⇒ Object
Returns the value of attribute performance_metrics.
-
#redis_db ⇒ Object
Returns the value of attribute redis_db.
-
#redis_namespace ⇒ Object
Returns the value of attribute redis_namespace.
-
#redis_url ⇒ Object
Returns the value of attribute redis_url.
-
#versioning(enabled: true, max_versions: Versioning::DEFAULT_MAX_VERSIONS) ⇒ Object
Returns the value of attribute versioning.
-
#warn_on_deprecated(enabled: true) ⇒ Object
Returns the value of attribute warn_on_deprecated.
Instance Method Summary collapse
- #active_record(model_class: nil, primary: false, **options) ⇒ Object
-
#adapter(type, **options, &block) ⇒ Object
DSL methods for configuration.
- #apply! ⇒ Object
- #circuit_breaker(threshold: nil, timeout: nil) ⇒ Object
-
#initialize ⇒ Config
constructor
A new instance of Config.
- #memory(**options) ⇒ Object
- #redis(url: nil, namespace: nil, db: nil, **options) ⇒ Object
-
#refresh_interval(seconds) ⇒ Object
Seconds between periodic re-reads of the shared backend (Adapters::Registry::DEFAULT_REFRESH_INTERVAL when unset).
-
#unknown_dependency_policy(policy = nil) ⇒ Object
How a prerequisite that exists neither in this process nor in the shared backend is treated: :satisfied (default, ignore it) or :unsatisfied (evaluate the dependent feature as off).
Constructor Details
#initialize ⇒ Config
Returns a new instance of Config.
8 9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/magick/config.rb', line 8 def initialize @warn_on_deprecated = false @async_updates = false @async_queue_limit = nil # nil => Adapters::AsyncWriter::DEFAULT_QUEUE_LIMIT @async_enqueue_timeout = nil # nil => Adapters::AsyncWriter::DEFAULT_ENQUEUE_TIMEOUT @memory_ttl = 3600 # 1 hour @circuit_breaker_threshold = 5 @circuit_breaker_timeout = 60 @redis_namespace = 'magick:features' @redis_db = nil # Use default database (0) unless specified @environment = defined?(::Rails) ? ::Rails.env.to_s : 'development' end |
Instance Attribute Details
#active_record_model_class ⇒ Object
Returns the value of attribute active_record_model_class.
5 6 7 |
# File 'lib/magick/config.rb', line 5 def active_record_model_class @active_record_model_class end |
#adapter_registry ⇒ Object
Returns the value of attribute adapter_registry.
5 6 7 |
# File 'lib/magick/config.rb', line 5 def adapter_registry @adapter_registry end |
#async_enqueue_timeout ⇒ Object
Returns the value of attribute async_enqueue_timeout.
5 6 7 |
# File 'lib/magick/config.rb', line 5 def async_enqueue_timeout @async_enqueue_timeout end |
#async_queue_limit ⇒ Object
Returns the value of attribute async_queue_limit.
5 6 7 |
# File 'lib/magick/config.rb', line 5 def async_queue_limit @async_queue_limit end |
#async_updates(enabled: true, queue_limit: nil, enqueue_timeout: nil) ⇒ Object
Asynchronous Redis writes. All async writes go through ONE serialized writer thread, so they reach Redis in the order they were issued and a burst costs one thread, not one per write.
queue_limit — pending writes held before backpressure kicks in.
enqueue_timeout — seconds a caller blocks on a full queue before the
write is dropped with a warning.
167 168 169 |
# File 'lib/magick/config.rb', line 167 def async_updates @async_updates end |
#audit_log(enabled: true, adapter: nil, retention: AuditLog::DEFAULT_RETENTION, max_entries: AuditLog::DEFAULT_MAX_ENTRIES, persist: true) ⇒ Object
enabled: false disables audit logging entirely (Magick.audit_log is nil). adapter: optional host-supplied sink; receives #append(entry) for every entry. retention: entries kept per feature in the durable, shared store. max_entries: entries kept in the per-process ring, across all features. persist: false keeps the ring (and any host adapter) but writes nothing to Redis/ActiveRecord — for hosts whose own adapter is the system of record.
140 141 142 |
# File 'lib/magick/config.rb', line 140 def audit_log @audit_log end |
#circuit_breaker_threshold ⇒ Object
Returns the value of attribute circuit_breaker_threshold.
5 6 7 |
# File 'lib/magick/config.rb', line 5 def circuit_breaker_threshold @circuit_breaker_threshold end |
#circuit_breaker_timeout ⇒ Object
Returns the value of attribute circuit_breaker_timeout.
5 6 7 |
# File 'lib/magick/config.rb', line 5 def circuit_breaker_timeout @circuit_breaker_timeout end |
#environment(name) ⇒ Object
Returns the value of attribute environment.
5 6 7 |
# File 'lib/magick/config.rb', line 5 def environment @environment end |
#memory_ttl(seconds) ⇒ Object
Returns the value of attribute memory_ttl.
5 6 7 |
# File 'lib/magick/config.rb', line 5 def memory_ttl @memory_ttl end |
#performance_metrics(enabled: true, redis_tracking: nil, batch_size: 100, flush_interval: 60, **_options) ⇒ Object
Returns the value of attribute performance_metrics.
5 6 7 |
# File 'lib/magick/config.rb', line 5 def performance_metrics @performance_metrics end |
#redis_db ⇒ Object
Returns the value of attribute redis_db.
5 6 7 |
# File 'lib/magick/config.rb', line 5 def redis_db @redis_db end |
#redis_namespace ⇒ Object
Returns the value of attribute redis_namespace.
5 6 7 |
# File 'lib/magick/config.rb', line 5 def redis_namespace @redis_namespace end |
#redis_url ⇒ Object
Returns the value of attribute redis_url.
5 6 7 |
# File 'lib/magick/config.rb', line 5 def redis_url @redis_url end |
#versioning(enabled: true, max_versions: Versioning::DEFAULT_MAX_VERSIONS) ⇒ Object
Returns the value of attribute versioning.
5 6 7 |
# File 'lib/magick/config.rb', line 5 def versioning @versioning end |
#warn_on_deprecated(enabled: true) ⇒ Object
Returns the value of attribute warn_on_deprecated.
5 6 7 |
# File 'lib/magick/config.rb', line 5 def warn_on_deprecated @warn_on_deprecated end |
Instance Method Details
#active_record(model_class: nil, primary: false, **options) ⇒ Object
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 112 113 |
# File 'lib/magick/config.rb', line 81 def active_record(model_class: nil, primary: false, **) @active_record_model_class = model_class if model_class @active_record_primary = primary active_record_adapter = configure_active_record_adapter(model_class: model_class, **) # Automatically create Registry adapter if it doesn't exist if @adapter_registry # If registry already exists, update it with the new Active Record adapter if active_record_adapter && @adapter_registry.is_a?(Adapters::Registry) @adapter_registry.instance_variable_set(:@active_record_adapter, active_record_adapter) # Update primary if specified @adapter_registry.instance_variable_set(:@primary, :active_record) if primary end else memory_adapter = configure_memory_adapter redis_adapter = configure_redis_adapter cb = Magick::CircuitBreaker.new( failure_threshold: @circuit_breaker_threshold, timeout: @circuit_breaker_timeout ) primary_adapter = primary ? :active_record : :memory @adapter_registry = Adapters::Registry.new( memory_adapter, redis_adapter, active_record_adapter: active_record_adapter, circuit_breaker: cb, primary: primary_adapter, ** ) end active_record_adapter end |
#adapter(type, **options, &block) ⇒ Object
DSL methods for configuration
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/magick/config.rb', line 22 def adapter(type, **, &block) case type.to_sym when :memory configure_memory_adapter(**) when :redis configure_redis_adapter(**) when :active_record configure_active_record_adapter(**) when :registry if block_given? instance_eval(&block) configure_registry_adapter else configure_registry_adapter(**) end else raise ArgumentError, "Unknown adapter type: #{type}" end end |
#apply! ⇒ Object
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
# File 'lib/magick/config.rb', line 210 def apply! # Apply configuration to Magick module Magick.adapter_registry = adapter_registry if adapter_registry # Set on whichever registry ends up live, including one built outside # this DSL, and only when the file said something: the registry's own # default must not be stomped by a nil here. if @refresh_interval_configured && Magick.adapter_registry.respond_to?(:refresh_interval=) Magick.adapter_registry.refresh_interval = @refresh_interval end # Apply performance metrics (preserve redis_tracking setting) if performance_metrics Magick.performance_metrics = performance_metrics # Re-apply redis_tracking setting after assignment (in case object was replaced) if defined?(@performance_metrics_redis_tracking) && !@performance_metrics_redis_tracking.nil? # Explicitly set value takes precedence Magick.performance_metrics.enable_redis_tracking(enable: @performance_metrics_redis_tracking) # Otherwise, auto-enable if Redis adapter is configured # Check Magick.adapter_registry (after it's been set) instead of local instance variable elsif Magick.adapter_registry.is_a?(Adapters::Registry) && Magick.adapter_registry.redis_available? # Always enable if Redis adapter is available (unless explicitly disabled above) Magick.performance_metrics.enable_redis_tracking(enable: true) end elsif Magick.performance_metrics # If no new performance_metrics was configured, but one exists, still try to enable Redis tracking # if Redis adapter is available and redis_tracking wasn't explicitly disabled # Only auto-enable if not explicitly disabled if Magick.adapter_registry.is_a?(Adapters::Registry) && Magick.adapter_registry.redis_available? && !(defined?(@performance_metrics_redis_tracking) && @performance_metrics_redis_tracking == false) Magick.performance_metrics.enable_redis_tracking(enable: true) end end # Read the ivars directly: calling the DSL methods here would re-run # them with their defaults and stomp explicit `enabled: false` settings. # Assign even when nil: `audit_log enabled: false` has to clear the # default instance Magick.configure creates, or opting out would leave # audit entries being written (durably, now) anyway. Magick.audit_log = @audit_log if @audit_log || @audit_log_configured Magick.versioning = @versioning if @versioning Magick.versioning_enabled = @versioning_enabled unless @versioning_enabled.nil? Magick.unknown_dependency_policy = @unknown_dependency_policy if @unknown_dependency_policy Magick.warn_on_deprecated = warn_on_deprecated end |
#circuit_breaker(threshold: nil, timeout: nil) ⇒ Object
155 156 157 158 |
# File 'lib/magick/config.rb', line 155 def circuit_breaker(threshold: nil, timeout: nil) @circuit_breaker_threshold = threshold if threshold @circuit_breaker_timeout = timeout if timeout end |
#memory(**options) ⇒ Object
42 43 44 |
# File 'lib/magick/config.rb', line 42 def memory(**) configure_memory_adapter(**) end |
#redis(url: nil, namespace: nil, db: nil, **options) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/magick/config.rb', line 46 def redis(url: nil, namespace: nil, db: nil, **) @redis_url = url if url @redis_namespace = namespace if namespace @redis_db = db if db redis_adapter = configure_redis_adapter(url: url, namespace: namespace, db: db, **) # Automatically create Registry adapter if it doesn't exist # This allows users to just call `redis url: ...` without needing to call `adapter :registry` if @adapter_registry # If registry already exists, update it with the new Redis adapter # This allows reconfiguring Redis without recreating the registry if redis_adapter && @adapter_registry.is_a?(Adapters::Registry) # Swap the Redis adapter; the registry retires the subscriber that was # listening on the previous one before starting a new one. @adapter_registry.redis_adapter = redis_adapter end else memory_adapter = configure_memory_adapter active_record_adapter = configure_active_record_adapter if defined?(::ActiveRecord::Base) cb = Magick::CircuitBreaker.new( failure_threshold: @circuit_breaker_threshold, timeout: @circuit_breaker_timeout ) @adapter_registry = Adapters::Registry.new( memory_adapter, redis_adapter, active_record_adapter: active_record_adapter, circuit_breaker: cb, ** ) end redis_adapter end |
#refresh_interval(seconds) ⇒ Object
Seconds between periodic re-reads of the shared backend
(Adapters::Registry::DEFAULT_REFRESH_INTERVAL when unset). This bounds how
stale a process can be when a Pub/Sub invalidation never reaches it.
false (or nil / 0) turns the refresh off, leaving Pub/Sub as the only
thing that updates a registered feature.
182 183 184 185 |
# File 'lib/magick/config.rb', line 182 def refresh_interval(seconds) @refresh_interval = seconds @refresh_interval_configured = true end |
#unknown_dependency_policy(policy = nil) ⇒ Object
How a prerequisite that exists neither in this process nor in the shared backend is treated: :satisfied (default, ignore it) or :unsatisfied (evaluate the dependent feature as off). See Magick.unknown_dependency_policy.
194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/magick/config.rb', line 194 def unknown_dependency_policy(policy = nil) return @unknown_dependency_policy if policy.nil? unless Magick::UNKNOWN_DEPENDENCY_POLICIES.include?(policy.to_sym) raise ArgumentError, "unknown_dependency_policy must be one of #{Magick::UNKNOWN_DEPENDENCY_POLICIES.inspect}, " \ "got #{policy.inspect}" end @unknown_dependency_policy = policy.to_sym end |