Class: Fosm::Lifecycle::SnapshotConfiguration

Inherits:
Object
  • Object
show all
Defined in:
lib/fosm/lifecycle/snapshot_configuration.rb

Overview

Configuration for when and what to snapshot during transitions. Supports multiple strategies: every, count, time, terminal, manual

Constant Summary collapse

STRATEGIES =

Strategy types

%i[every count time terminal manual].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSnapshotConfiguration

Returns a new instance of SnapshotConfiguration.



11
12
13
14
15
16
# File 'lib/fosm/lifecycle/snapshot_configuration.rb', line 11

def initialize
  @strategy = :manual  # default: no automatic snapshots
  @attributes = []     # empty = snapshot all readable attributes
  @interval = nil      # for :count (transitions) or :time (seconds)
  @conditions = []     # additional conditions that must be met
end

Instance Attribute Details

#conditionsObject (readonly)

Returns the value of attribute conditions.



9
10
11
# File 'lib/fosm/lifecycle/snapshot_configuration.rb', line 9

def conditions
  @conditions
end

#intervalObject (readonly)

Returns the value of attribute interval.



9
10
11
# File 'lib/fosm/lifecycle/snapshot_configuration.rb', line 9

def interval
  @interval
end

#strategyObject (readonly)

Returns the value of attribute strategy.



9
10
11
# File 'lib/fosm/lifecycle/snapshot_configuration.rb', line 9

def strategy
  @strategy
end

Instance Method Details

#attributesObject

Returns the configured attributes



19
20
21
# File 'lib/fosm/lifecycle/snapshot_configuration.rb', line 19

def attributes
  @attributes
end

#build_snapshot(record) ⇒ Hash

Build the snapshot data from a record

Parameters:

  • record (ActiveRecord::Base)

    the record to snapshot

Returns:

  • (Hash)

    the snapshot data



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/fosm/lifecycle/snapshot_configuration.rb', line 82

def build_snapshot(record)
  attrs = @attributes.any? ? @attributes : default_attributes(record)

  snapshot = {}
  attrs.each do |attr|
    value = read_attribute(record, attr)
    snapshot[attr] = serialize_value(value)
  end

  # Always include core FOSM metadata
  snapshot["_fosm_snapshot_meta"] = {
    "snapshot_at" => Time.current.iso8601,
    "record_class" => record.class.name,
    "record_id" => record.id.to_s
  }

  snapshot
end

#count(n) ⇒ Object

DSL: snapshot every N transitions Usage: snapshot every: 10



31
32
33
34
# File 'lib/fosm/lifecycle/snapshot_configuration.rb', line 31

def count(n)
  @strategy = :count
  @interval = n
end

#everyObject

DSL: snapshot on every transition Usage: snapshot :every



25
26
27
# File 'lib/fosm/lifecycle/snapshot_configuration.rb', line 25

def every
  @strategy = :every
end

#manualObject

DSL: manual snapshots only (default) Usage: snapshot :manual



51
52
53
# File 'lib/fosm/lifecycle/snapshot_configuration.rb', line 51

def manual
  @strategy = :manual
end

#set_attributes(*attrs) ⇒ Object

DSL: specify which attributes to snapshot Usage: snapshot_attributes :amount, :status, :line_items_count

snapshot_attributes %i[amount status]  # array also works


58
59
60
# File 'lib/fosm/lifecycle/snapshot_configuration.rb', line 58

def set_attributes(*attrs)
  @attributes = attrs.flatten.map(&:to_s)
end

#should_snapshot?(transition_count:, seconds_since_last:, to_state:, to_state_terminal:, force: false) ⇒ Boolean

Check if a snapshot should be taken for this transition

Parameters:

  • transition_count (Integer)

    transitions since last snapshot

  • seconds_since_last (Float)

    seconds since last snapshot

  • to_state (String)

    the state we’re transitioning to

  • to_state_terminal (Boolean)

    whether the destination state is terminal

  • force (Boolean) (defaults to: false)

    manual override to force snapshot

Returns:

  • (Boolean)


68
69
70
71
72
73
74
75
76
77
# File 'lib/fosm/lifecycle/snapshot_configuration.rb', line 68

def should_snapshot?(transition_count:, seconds_since_last:, to_state:, to_state_terminal:, force: false)
  return true if force
  return false if @strategy == :manual
  return true if @strategy == :every
  return true if @strategy == :terminal && to_state_terminal
  return true if @strategy == :count && transition_count >= @interval
  return true if @strategy == :time && seconds_since_last >= @interval

  false
end

#terminalObject

DSL: snapshot only on terminal states Usage: snapshot :terminal



45
46
47
# File 'lib/fosm/lifecycle/snapshot_configuration.rb', line 45

def terminal
  @strategy = :terminal
end

#time(seconds) ⇒ Object

DSL: snapshot if last snapshot was more than N seconds ago Usage: snapshot time: 300 (5 minutes)



38
39
40
41
# File 'lib/fosm/lifecycle/snapshot_configuration.rb', line 38

def time(seconds)
  @strategy = :time
  @interval = seconds
end