Module: Smith::Doctor::Checks::PersistenceCapabilities

Defined in:
lib/smith/doctor/checks/persistence_capabilities.rb

Overview

Reports which optional capabilities the configured persistence adapter supports. Hosts who depend on optimistic locking but configure a cache-backed adapter (CacheStore / RailsCache) need to know up front that store_versioned silently falls back to plain store. Workflow#persist! warns once per adapter class per Smith boot, but doctor surfaces it eagerly.

Constant Summary collapse

OPTIONAL_CAPABILITIES =
Smith::PersistenceAdapters::OPTIONAL_METHODS

Class Method Summary collapse

Class Method Details

.capability_available?(adapter, capability) ⇒ Boolean

Returns:

  • (Boolean)


35
36
37
38
39
40
41
42
43
# File 'lib/smith/doctor/checks/persistence_capabilities.rb', line 35

def capability_available?(adapter, capability)
  return false unless Smith::PersistenceAdapters.supports?(adapter, capability)
  return true unless capability == :persistence_identity

  identity = adapter.persistence_identity
  identity.is_a?(String) && !identity.empty? && identity.bytesize <= 256
rescue StandardError
  false
end

.report_missing_adapter(report) ⇒ Object



45
46
47
48
49
50
51
52
53
# File 'lib/smith/doctor/checks/persistence_capabilities.rb', line 45

def report_missing_adapter(report)
  report.add(
    name: "persistence.capabilities",
    status: :warn,
    message: "No persistence adapter configured",
    detail: "Smith.config.persistence_adapter is nil and Smith.config.test_mode is false. " \
            "Hosts using durable workflows must set persistence_adapter."
  )
end

.report_missing_capabilities(report, adapter, missing) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/smith/doctor/checks/persistence_capabilities.rb', line 64

def report_missing_capabilities(report, adapter, missing)
  report.add(
    name: "persistence.capabilities",
    status: :warn,
    message: "#{adapter.class.name} missing optional capabilities: #{missing.join(", ")}",
    detail: "Smith will fall back where possible: non-versioned writes when store_versioned " \
            "is missing, and payload updated_at parsing when heartbeat methods are missing. " \
            "Without transaction_open? and transaction_identity, exact commit-aware " \
            "split-step confirmation is unavailable. " \
            "If transaction_open? returns true, transaction_identity is required and " \
            "split-step preparation fails before writing when it is missing. " \
            "Use RedisStore with an explicit persistence identity or Memory for full versioning " \
            "and heartbeat coverage; ActiveRecordStore covers optimistic locking and exact " \
            "transaction identity when configured with an identity."
  )
end

.report_supported_capabilities(report, adapter) ⇒ Object



55
56
57
58
59
60
61
62
# File 'lib/smith/doctor/checks/persistence_capabilities.rb', line 55

def report_supported_capabilities(report, adapter)
  report.add(
    name: "persistence.capabilities",
    status: :pass,
    message: "#{adapter.class.name} supports all optional persistence capabilities",
    detail: "Supported: #{OPTIONAL_CAPABILITIES.join(", ")}"
  )
end

.resolve_adapterObject



29
30
31
32
33
# File 'lib/smith/doctor/checks/persistence_capabilities.rb', line 29

def resolve_adapter
  Smith.persistence_adapter
rescue StandardError
  nil
end

.run(report) ⇒ Object



19
20
21
22
23
24
25
26
27
# File 'lib/smith/doctor/checks/persistence_capabilities.rb', line 19

def run(report)
  adapter = resolve_adapter
  return report_missing_adapter(report) if adapter.nil?

  missing = OPTIONAL_CAPABILITIES.reject { |cap| capability_available?(adapter, cap) }
  return report_supported_capabilities(report, adapter) if missing.empty?

  report_missing_capabilities(report, adapter, missing)
end