Module: Siding::Staleness

Defined in:
lib/siding/staleness.rb

Defined Under Namespace

Classes: Events, Verdict

Constant Summary collapse

FRESH =
:fresh
RELOADABLE =
:reloadable
REBOOT =
:reboot
DEPENDENCIES_CHANGED =
:dependencies_changed
SOURCE_CHANGED =
:source_changed
SOURCE_ADDED_OR_REMOVED =
:source_added_or_removed
ENVIRONMENT_CHANGED =
:environment_changed
MAX_TRIGGER_PATHS =
25

Class Method Summary collapse

Class Method Details

.stamp_of(entry) ⇒ Object



105
# File 'lib/siding/staleness.rb', line 105

def stamp_of(entry) = "#{entry.size}:#{format('%.6f', entry.mtime)}"

.strategy_for(changed_scopes) ⇒ Object



98
99
100
101
102
103
# File 'lib/siding/staleness.rb', line 98

def strategy_for(changed_scopes)
  return FRESH if changed_scopes.empty?
  return RELOADABLE if changed_scopes.all? { |scope| scope == LoadManifest::RELOADABLE }

  REBOOT
end

.validate(manifest, env: ENV) ⇒ 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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/siding/staleness.rb', line 46

def validate(manifest, env: ENV)
  reasons = []
  triggers = []
  changed_scopes = []

  bundle_token = LoadManifest.token_for(manifest.bundle_files)
  if bundle_token != manifest.bundle_token
    reasons << DEPENDENCIES_CHANGED
    triggers.concat(manifest.bundle_files)
    changed_scopes << LoadManifest::REBOOT
  end

  files = manifest.file_entries.map do |entry|
    stamp = LoadManifest.stamp_for(entry.path)
    unless stamp == stamp_of(entry)
      reasons << SOURCE_CHANGED
      triggers << entry.path
      changed_scopes << entry.scope
    end
    [entry.path, stamp]
  end

  directories = manifest.directory_entries.map do |entry|
    digest = LoadManifest.entry_digest_for(entry.path, recursive: entry.recursive)
    unless digest == entry.entry_digest
      reasons << SOURCE_ADDED_OR_REMOVED
      triggers << entry.path
      changed_scopes << entry.scope
    end
    [entry.path, digest]
  end

  envs = manifest.env_entries.map do |entry|
    digest = LoadManifest.digest_env_value(env[entry.key])
    unless digest == entry.value_digest
      reasons << ENVIRONMENT_CHANGED
      triggers << entry.key
      # Always reboot-class: a value consumed at boot is already inside a constant, and no
      # reloader can reach in there and change it.
      changed_scopes << LoadManifest::REBOOT
    end
    [entry.key, digest]
  end

  Verdict.new(
    strategy: strategy_for(changed_scopes),
    reasons: reasons.uniq,
    trigger_paths: triggers.first(MAX_TRIGGER_PATHS),
    revision_label: LoadManifest.label_for(bundle_token:, files:, directories:, envs:)
  )
end