Module: Hecks::Adapters::PostgresEra::LineageManager::MergeCoordinator

Included in:
Hecks::Adapters::PostgresEra::LineageManager
Defined in:
lib/hecks/adapters/driven/postgres_era/lineage_manager/merge_coordinator.rb

Overview

Tail-merge, driven from bin/merge_tail: interleave the old world's post-cut writes into the head by their recorded global ordinals, under the full audit, in one transaction.

Instance Method Summary collapse

Instance Method Details

#merge!(registry:, bluebook:, settings:, winners: {}) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/hecks/adapters/driven/postgres_era/lineage_manager/merge_coordinator.rb', line 13

def merge!(registry:, bluebook:, settings:, winners: {})
  db = PostgresEra.connect_for(bluebook.name, settings)
  lineage = Lineage.new(db, bluebook.name, formerly_known_as: bluebook.formerly_known_as)
  lineage.ensure_base!

  held = lineage.eras
  raise Runtime::WiringError, "nothing to merge — #{bluebook.name} stands at era 1" if held.size < 2

  latest = held.last
  chain = edge_chain(registry, bluebook, held[0..-2], latest[:label])

  audit = lambda do
    violations = []
    bluebook.aggregates.each do |aggregate|
      rows = db.exec("SELECT id, state FROM #{PG::Connection.quote_ident(lineage.head_view(aggregate.storage_name))}")
               .to_h { |row| [row["id"], JSON.parse(row["state"])] }
      verdict = Translation::Audit.check(aggregate: aggregate, declared: nil, before: rows, after: rows)
      violations.concat(verdict.violations)
    end
    violations
  end

  lineage.merge_tail!(aggregates: bluebook.aggregates, edges: chain, winners: winners, audit: audit)
ensure
  db&.close
end