Module: Smith::Workflow::Durability

Included in:
Smith::Workflow
Defined in:
lib/smith/workflow/durability.rb

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



8
9
10
# File 'lib/smith/workflow/durability.rb', line 8

def self.included(base)
  base.extend(ClassMethods)
end

Instance Method Details

#advance_persisted!(key = nil, adapter: Smith.persistence_adapter, on_step: nil) ⇒ Object



274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/smith/workflow/durability.rb', line 274

def advance_persisted!(key = nil, adapter: Smith.persistence_adapter, on_step: nil)
  return if terminal?

  resolved_key = resolve_persistence_key!(key)
  ensure_transition_budget!
  mark_step_in_progress! if strict_idempotency?
  persist!(resolved_key, adapter:)
  step = advance!
  clear_step_in_progress!
  persist!(resolved_key, adapter:) if step
  invoke_on_step_callback(step, on_step) if step
  step
rescue StandardError
  clear_pre_step_marker!(resolved_key, adapter:) if defined?(resolved_key) && resolved_key
  raise
end

#clear_persisted!(key = nil, adapter: Smith.persistence_adapter) ⇒ Object



307
308
309
310
311
# File 'lib/smith/workflow/durability.rb', line 307

def clear_persisted!(key = nil, adapter: Smith.persistence_adapter)
  resolved_key = resolve_persistence_key!(key)
  persistence_adapter!(adapter).delete(resolved_key)
  self
end

#clear_step_in_progress!Object



317
318
319
# File 'lib/smith/workflow/durability.rb', line 317

def clear_step_in_progress!
  @step_in_progress = false
end

#mark_step_in_progress!Object



313
314
315
# File 'lib/smith/workflow/durability.rb', line 313

def mark_step_in_progress!
  @step_in_progress = true
end

#persist!(key = nil, adapter: Smith.persistence_adapter) ⇒ Object



291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/smith/workflow/durability.rb', line 291

def persist!(key = nil, adapter: Smith.persistence_adapter)
  resolved_key = resolve_persistence_key!(key)
  store = persistence_adapter!(adapter)
  previous_version = @persistence_version || 0
  next_version = previous_version + 1
  payload = JSON.generate(to_state.merge(persistence_version: next_version))

  dispatch_store!(store, resolved_key, payload, previous_version: previous_version)

  # Increment ONLY after successful store. On PersistenceVersionConflict
  # (raised by store_versioned), @persistence_version stays at the
  # previous value so callers can rescue + restore + retry cleanly.
  @persistence_version = next_version
  self
end

#run_persisted!(key = nil, adapter: Smith.persistence_adapter, on_step: nil) ⇒ Object



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# File 'lib/smith/workflow/durability.rb', line 243

def run_persisted!(key = nil, adapter: Smith.persistence_adapter, on_step: nil)
  return build_run_result([]) if terminal?

  resolved_key = resolve_persistence_key!(key)
  steps = []
  persist!(resolved_key, adapter:)

  until terminal?
    ensure_transition_budget!

    if strict_idempotency?
      mark_step_in_progress!
      persist!(resolved_key, adapter:)
    end

    begin
      step = advance!
    rescue StandardError
      clear_pre_step_marker!(resolved_key, adapter:)
      raise
    end
    steps << step if step

    clear_step_in_progress!
    persist!(resolved_key, adapter:)
    invoke_on_step_callback(step, on_step) if step
  end

  build_run_result(steps)
end