Class: Ucode::Repo::BuildReportAccumulator
- Inherits:
-
Object
- Object
- Ucode::Repo::BuildReportAccumulator
- Defined in:
- lib/ucode/repo/build_report_accumulator.rb
Overview
Observes CodepointWriter and tallies per-tier + per-block statistics for the canonical build report (TODO 21).
Wire as the observer: kwarg on CodepointWriter:
accumulator = BuildReportAccumulator.new(unicode_version: "17.0.0")
writer = CodepointWriter.new(root, resolver: resolver, observer: accumulator)
coordinator.each_codepoint { |cp| writer.write(cp) }
report = accumulator.to_report
The accumulator is thread-safe — the writer's worker pool calls
#call from multiple threads.
Semantics
assigned counts every codepoint the writer attempted (passed
the block_id guard). built counts codepoints whose resolver
returned a glyph. skipped counts codepoints that resolved to
nil (no tier produced a glyph). failed counts exceptions
recorded via #record_failure (the writer rescues nothing;
the orchestrating command decides what to surface).
by_tier counts ONLY the winning tier per codepoint (not the
overlap semantics mentioned in TODO 21's example). TODO 21
notes the overlap counts as descriptive; the per-codepoint
winning tier is the load-bearing number for validation.
Instance Method Summary collapse
-
#call(codepoint, result) ⇒ void
Observer entry point — invoked by CodepointWriter#write as
observer.call(codepoint, result). -
#initialize(unicode_version:, ucode_version:) ⇒ BuildReportAccumulator
constructor
A new instance of BuildReportAccumulator.
-
#record_failure(codepoint, error, tier: nil) ⇒ void
Record an exception encountered while building a codepoint.
-
#to_report ⇒ Ucode::Models::BuildReport
Build the immutable Models::BuildReport snapshot.
Constructor Details
#initialize(unicode_version:, ucode_version:) ⇒ BuildReportAccumulator
Returns a new instance of BuildReportAccumulator.
46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/ucode/repo/build_report_accumulator.rb', line 46 def initialize(unicode_version:, ucode_version:) @unicode_version = unicode_version @ucode_version = ucode_version @totals = { assigned: 0, built: 0, skipped: 0, failed: 0 } @by_tier = Hash.new(0) @by_block = Hash.new do |h, name| h[name] = { assigned: 0, built: 0, tier_breakdown: Hash.new(0) } end @failures = [] @mutex = Mutex.new end |
Instance Method Details
#call(codepoint, result) ⇒ void
This method returns an undefined value.
Observer entry point — invoked by CodepointWriter#write as
observer.call(codepoint, result). Records one attempt.
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/ucode/repo/build_report_accumulator.rb', line 64 def call(codepoint, result) synchronize do @totals[:assigned] += 1 block_stats = @by_block[codepoint.block_id] block_stats[:assigned] += 1 if result @totals[:built] += 1 tier = wire_tier(result.tier) @by_tier[tier] += 1 block_stats[:built] += 1 block_stats[:tier_breakdown][tier] += 1 else @totals[:skipped] += 1 end end end |
#record_failure(codepoint, error, tier: nil) ⇒ void
This method returns an undefined value.
Record an exception encountered while building a codepoint. The orchestrating command calls this when rescuing around writer.write; the writer itself does not rescue.
90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/ucode/repo/build_report_accumulator.rb', line 90 def record_failure(codepoint, error, tier: nil) synchronize do @totals[:failed] += 1 @failures << Ucode::Models::BuildReport::Failure.new( codepoint: codepoint&.cp, block_name: codepoint&.block_id, tier: tier&.to_s, error_class: error.class.name, message: error., backtrace: Array(error.backtrace).first(10), ) end end |
#to_report ⇒ Ucode::Models::BuildReport
Build the immutable Models::BuildReport snapshot.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/ucode/repo/build_report_accumulator.rb', line 106 def to_report synchronize do Ucode::Models::BuildReport.new( unicode_version: @unicode_version, ucode_version: @ucode_version, generated_at: Time.now.utc.iso8601, totals: Ucode::Models::BuildReport::Totals.new(@totals), by_tier: @by_tier.dup, by_block: @by_block.map do |name, stats| Ucode::Models::BuildReport::BlockSummary.new( name: name, assigned: stats[:assigned], built: stats[:built], tier_breakdown: stats[:tier_breakdown].dup, ) end, failures: @failures.dup, ) end end |