Class: Magick::Versioning
- Inherits:
-
Object
- Object
- Magick::Versioning
- Defined in:
- lib/magick/versioning.rb
Defined Under Namespace
Classes: Version
Constant Summary collapse
- DEFAULT_MAX_VERSIONS =
50- STORE_PREFIX =
Version history lives under a reserved pseudo-feature namespace so that feature reads (get_all_data) never drag snapshot blobs along, and so deleting a feature does not destroy its ActiveRecord archive row.
'__magick_versions:'
Instance Attribute Summary collapse
-
#max_versions ⇒ Object
readonly
Returns the value of attribute max_versions.
Instance Method Summary collapse
-
#get_versions(feature_name, all: false) ⇒ Object
Hot window (last max_versions, memory/Redis) by default; all: true merges the unlimited ActiveRecord archive when one is configured.
-
#initialize(adapter_registry, max_versions: DEFAULT_MAX_VERSIONS) ⇒ Versioning
constructor
A new instance of Versioning.
-
#record_change(feature, action: nil, created_by: nil, snapshot: nil) ⇒ Object
Called by Feature#record_change after every successful mutation.
-
#rollback(feature_name, version) ⇒ Object
Restore the feature to the snapshot stored in the given version, then record the rollback itself as a new version + audit entry (history only ever rolls forward).
-
#save_version(feature_name, version: nil, created_by: nil) ⇒ Object
Explicit manual snapshot.
Constructor Details
#initialize(adapter_registry, max_versions: DEFAULT_MAX_VERSIONS) ⇒ Versioning
Returns a new instance of Versioning.
37 38 39 40 41 42 43 44 |
# File 'lib/magick/versioning.rb', line 37 def initialize(adapter_registry, max_versions: DEFAULT_MAX_VERSIONS) @adapter_registry = adapter_registry @max_versions = max_versions.to_i.positive? ? max_versions.to_i : DEFAULT_MAX_VERSIONS # Process-local cache of the hot window, rehydrated lazily from the # adapters so history survives restarts and is shared across containers. @hot = {} @mutex = Mutex.new end |
Instance Attribute Details
#max_versions ⇒ Object (readonly)
Returns the value of attribute max_versions.
46 47 48 |
# File 'lib/magick/versioning.rb', line 46 def max_versions @max_versions end |
Instance Method Details
#get_versions(feature_name, all: false) ⇒ Object
Hot window (last max_versions, memory/Redis) by default; all: true merges the unlimited ActiveRecord archive when one is configured.
64 65 66 67 68 69 70 71 |
# File 'lib/magick/versioning.rb', line 64 def get_versions(feature_name, all: false) name = feature_name.to_s hot = @mutex.synchronize { hot_window(name).dup } return hot unless all older = archive_versions(name).reject { |a| hot.any? { |h| h.version == a.version } } (older + hot).sort_by(&:version) end |
#record_change(feature, action: nil, created_by: nil, snapshot: nil) ⇒ Object
Called by Feature#record_change after every successful mutation. snapshot: allows callers (delete) to capture state before the mutation.
57 58 59 60 |
# File 'lib/magick/versioning.rb', line 57 def record_change(feature, action: nil, created_by: nil, snapshot: nil) data = snapshot ? deep_symbolize(JSON.parse(JSON.generate(snapshot))) : snapshot_of(feature) append(feature.name, data, created_by: created_by, action: action) end |
#rollback(feature_name, version) ⇒ Object
Restore the feature to the snapshot stored in the given version, then record the rollback itself as a new version + audit entry (history only ever rolls forward). Restores state wholesale: value (including false/ empty), status, group, the entire targeting hash, and dependencies.
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/magick/versioning.rb', line 77 def rollback(feature_name, version) entry = find_version(feature_name, version) return false unless entry feature = Magick.features[feature_name.to_s] || Magick[feature_name] Magick.suppress_change_recording do feature.restore_snapshot!(entry.feature_data) end actor = Magick.current_actor Magick.audit_log&.log(feature_name, 'rollback', user_id: actor, changes: { rolled_back_to: version }) record_change(feature, action: 'rollback', created_by: actor) if defined?(Magick::Rails::Events) && Magick::Rails::Events.rails8? Magick::Rails::Events.rollback(feature_name, version: version) end true end |
#save_version(feature_name, version: nil, created_by: nil) ⇒ Object
Explicit manual snapshot. Kept as public API from earlier releases; since 1.5.0 every Feature mutation also snapshots automatically.
50 51 52 53 |
# File 'lib/magick/versioning.rb', line 50 def save_version(feature_name, version: nil, created_by: nil) feature = Magick.features[feature_name.to_s] || Magick[feature_name] append(feature.name, snapshot_of(feature), version: version, created_by: created_by, action: 'manual') end |