Class: Textus::Maintenance::Reconcile

Inherits:
Object
  • Object
show all
Extended by:
Contract::DSL
Defined in:
lib/textus/maintenance/reconcile.rb

Overview

Two-phase convergence pass (ADR 0093). Replaces the old Lifecycle-reporter sweep.

Phase 1 — Produce (non-destructive): re-render ALL derived entries (cheap, idempotent) plus every intake entry past its source.ttl (stale-only, so external sources are not hammered). Driven by Produce::Engine.

Phase 2 — Retention sweep (destructive): drop or archive entries past their retention ttl. Driven by Domain::Retention::Sweep. The old refresh/warn actions are gone — intake re-pull is now Produce’s responsibility.

Instance Method Summary collapse

Methods included from Contract::DSL

arg, around, cli, cli_stdin, contract, contract?, summary, surfaces, verb, view

Constructor Details

#initialize(container:, call:) ⇒ Reconcile

Returns a new instance of Reconcile.



28
29
30
31
# File 'lib/textus/maintenance/reconcile.rb', line 28

def initialize(container:, call:)
  @container = container
  @call      = call
end

Instance Method Details

#call(prefix: nil, zone: nil, dry_run: false) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/textus/maintenance/reconcile.rb', line 33

def call(prefix: nil, zone: nil, dry_run: false)
  file_stat = Textus::Ports::Storage::FileStat.new
  retention_rows = Textus::Domain::Retention::Sweep.new(
    manifest: @container.manifest, file_stat: file_stat, clock: Textus::Ports::Clock.new,
  ).call(prefix: prefix, zone: zone)

  produce_keys = produce_scope(prefix, zone, file_stat)
  health = Read::Doctor.new(container: @container, call: @call).call
  return dry_run_result(produce_keys, retention_rows, health) if dry_run

  # reconcile is the authoritative "make everything current now" pass, so
  # it subsumes any in-flight reactive produce: drain pending async
  # produce-on-write threads first, both to fold their work in and to free
  # the shared maintenance lock (BuildLock is non-blocking — a thread still
  # holding it would make the acquire below raise BuildInProgress). ADR 0093.
  Textus::Produce::Engine::AsyncRunner.drain

  Textus::Ports::BuildLock.with(root: @container.root) do
    produced = Textus::Produce::Engine.new(container: @container, call: @call).call(keys: produce_keys)
    swept = apply(retention_rows)
    publish_failed(swept[:failed]) unless swept[:failed].empty?
    apply_result(produced, swept, health)
  end
end