Skip to content

Add :compact-aware Base.show methods for callback events and supporting types#602

Merged
bvdmitri merged 19 commits into
mainfrom
implement_show_methods_trace_events
May 4, 2026
Merged

Add :compact-aware Base.show methods for callback events and supporting types#602
bvdmitri merged 19 commits into
mainfrom
implement_show_methods_trace_events

Conversation

@RetrospectiveRotations
Copy link
Copy Markdown
Contributor

Resolves #599.

Summary

  • Adds Base.show methods for every callback event in src/callbacks.jl (Before/AfterMessageRuleCallEvent, Before/AfterProductOfTwoMessagesEvent, Before/AfterProductOfMessagesEvent, Before/AfterFormConstraintAppliedEvent, Before/AfterMarginalComputationEvent) plus the supporting types they reference (MessageMapping, MessageProductContext, FormConstraintCheckEach, FormConstraintCheckLast, AnnotationDict).
  • Methods honor the standard IOContext :compact flag:
    • :compact => true (used by trace loggers like the RxInfer TensorBoardLoggerExt) → short, single-line form: nmsgs=N, 4-char span prefix.
    • :compact => false (default — REPL, Pluto, Jupyter) → full form: actual messages=(Message(...), ...), full UUID span_id=…, and the otherwise-elided context fields.
  • _show_span helper emits no field at all when span_id === nothing (callbacks disabled), instead of span=nothing.
  • AnnotationDict switched from MIME"text/plain" dispatch to :compact branching for consistency.
  • MessageMapping.show now reuses the existing unval helper from src/helpers/helpers.jl:81 instead of a local duplicate.

Why

Trace loggers were rendering raw struct dumps like BeforeMessageRuleCallEvent{ReactiveMP.MessageMapping{…}, …}(...) because the events had no Base.show. This makes TBLogger Text-tag breadcrumbs unreadable (RxInfer.jl#638).

Review feedback applied

All four points from @bvdmitri's review on this issue:

  1. _show_span no longer prints span=nothing — the field is omitted entirely.
  2. Base.show honors the :compact flag rather than compacting unconditionally — full content (actual messages) is preserved for REPL/Pluto, compact form is opt-in for trace loggers.
  3. The same :compact distinction applies to FormConstraintCheckEach/Last, MessageMapping, MessageProductContext, and AnnotationDict.
  4. _message_mapping_names was deleted; the show method uses the existing unval helper.

Downstream

Pairs with the matching RxInfer side: ReactiveBayes/RxInfer.jl#638 / branch feat/event-show-methods. RxInfer's TensorBoardLoggerExt was updated to render via sprint(show, ev; context = :compact => true) so it gets the short trace form.

Helpers keep the single-line event repr compact (first 4 hex chars +
ellipsis) while remaining greppable across matching Before/After pairs;
the long-form variant prints the full UUID for MIME("text/plain") show
methods that follow.
Renders MessageMapping as a single-line summary:
`MessageMapping(NormalMeanVariance, :out, msgs=[:mu, :tau])` so trace
events that carry a mapping field stop dumping its full struct contents.
The names tuples are stored as `Val{(...)}()` for type stability;
extract via a small internal helper.
Single-line summary that surfaces the two distinguishing knobs (form
constraint check strategy and fold direction) instead of dumping every
default kwarg, which dominated the trace output for product events.
Default repr is now `AnnotationDict(n=K)` so the trace logger does not
inline annotation values that may themselves be large distributions.
Full key/value listing moves to `show(io, MIME"text/plain", ann)` for
interactive debugging. Test updated to assert both forms.
Renders as `CheckEach` and `CheckLast` instead of the fully-qualified
type name, so MessageProductContext.show stays compact in trace output.
Renders mapping inline (now that MessageMapping has its own show), counts
messages / marginals tuples instead of dumping them, and truncates the
span identifier to the first 4 hex chars so the matching Before/After
pair stays visually correlatable in compact log output.
Surfaces the variable label, the two factor messages being multiplied,
and (for the After variant) the result distribution + annotation count,
joined to its Before partner via the truncated span identifier.
Replaces the full-tuple dump of messages with a count and surfaces only
the variable label, message count, and (for After) the resulting message
plus the span id linking it back to the Before event.
Compact one-line summary listing the variable label, the constraint
check strategy (rendered via the new short FormConstraintCheck shows),
the input distribution, and (After only) the constrained result.
Final Tier B event: variable label, message count and (After only) the
computed marginal, joined to its Before partner via the span identifier.
With this in place every `Event` subtype defined in callbacks.jl has a
compact, single-line representation suitable for trace-logger output.
Locks down the new compact `Base.show` output for every Before/After
event pair plus the supporting types they render (MessageMapping,
MessageProductContext, FormConstraintCheck variants). Includes a
regression guard that fails if a future change reintroduces the raw
struct dump shape (`MessageMapping{` or `Event{` braces) that issue
#599 / RxInfer.jl#638 set out to remove. Also covers the `nothing`
span_id path so disabled callbacks do not panic.
Records the user-visible behavior change for the upcoming 6.x release:
trace-logger output for callback events is now compact and structured
instead of dumping raw struct contents, and AnnotationDict's compact
form drops inline values in favour of a count.
Captures the design rationale (which package, which events, format
conventions, sequencing options) that produced the Base.show methods
landing in this branch. Kept alongside the code so the trade-offs
behind compact-vs-MIME-form choices stay discoverable for the eventual
RxInfer-side cleanup PR.
Drop the local _message_mapping_names helper in favor of the existing
src/helpers/helpers.jl unval, which has the same Val{S} unwrapping
semantics and is already used by the annotation input-arguments code.
Rework all event Base.show methods plus their supporting types
(MessageMapping, MessageProductContext, FormConstraintCheckEach/Last,
AnnotationDict) to honor the standard :compact IOContext flag instead
of unconditionally emitting the compact form.

Default form (REPL, Pluto, Jupyter — :compact => false) prints actual
messages/marginals, the full UUID span id, and the additional context
fields. Compact form (used by trace loggers like RxInfer's
TensorBoardLoggerExt) keeps the previous nmsgs=N / 4-char span prefix
shape so log lines stay greppable and one-per-event.

Also drop the span=nothing noise when callbacks are disabled — the
helper now emits no field at all when span_id === nothing. The
AnnotationDict show switches from MIME-based dispatch to the same
:compact branching for consistency with the rest of the family.

Tests cover both forms and assert that span is omitted when nil.
Update the [Unreleased] entries to describe the :compact-flag-based
design instead of the previous unconditional-compact framing, and call
out that span fields are now omitted entirely when callbacks are
disabled.
@github-actions
Copy link
Copy Markdown
Contributor

🤖 Code Formatting

Your PR still has some code formatting issues. I've updated PR #603 with the necessary formatting changes.

You can merge that PR into this branch to fix the code style check.

Alternatively, you can run make format locally and push the changes yourself.

@github-actions
Copy link
Copy Markdown
Contributor

🤖 Code Formatting

Your PR still has some code formatting issues. I've updated PR #603 with the necessary formatting changes.

You can merge that PR into this branch to fix the code style check.

Alternatively, you can run make format locally and push the changes yourself.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 29, 2026

Codecov Report

❌ Patch coverage is 98.70130% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.41%. Comparing base (f46afbf) to head (d37dead).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/message.jl 92.59% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #602      +/-   ##
==========================================
+ Coverage   82.02%   82.41%   +0.38%     
==========================================
  Files         208      208              
  Lines        6402     6555     +153     
==========================================
+ Hits         5251     5402     +151     
- Misses       1151     1153       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@bvdmitri
Copy link
Copy Markdown
Member

bvdmitri commented May 4, 2026

The documentation build fails with

┌ Error: 1 docstring not included in the manual:
│ 
│     ReactiveMP._show_span :: Tuple{IO, Any}
│ 
│ These are docstrings in the checked modules (configured with the modules keyword)

All documented functions must be present in the @docs section somewhere in the documentation pages in the docs/ folder. If you want to have a documented "internal" function, which does not really need to be in the main documentation, you can always use a comment instead of the docstring above the function.

@RetrospectiveRotations
Copy link
Copy Markdown
Contributor Author

Fixed. Checks now pass

Copy link
Copy Markdown
Member

@bvdmitri bvdmitri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Appreciated!

@bvdmitri bvdmitri merged commit 61ab53e into main May 4, 2026
9 checks passed
@bvdmitri bvdmitri deleted the implement_show_methods_trace_events branch May 4, 2026 09:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Task]: Create show methods for Events

2 participants