Skip to content

NMS-20204: Reduce per-event overhead in the event translator - #8779

Open
marshallmassengill wants to merge 3 commits into
foundation-2025from
mm/NMS-20204-smoke
Open

NMS-20204: Reduce per-event overhead in the event translator#8779
marshallmassengill wants to merge 3 commits into
foundation-2025from
mm/NMS-20204-smoke

Conversation

@marshallmassengill

Copy link
Copy Markdown
Contributor

EventTranslatorConfigFactory repeated most of its work on every event.

  • sql values query once per event instead of twice
  • Regexes compile at load, not per event (and not per parm)
  • Events clone only after a mapping matches, not before
  • cloneEvent() copies fields instead of serializing: ~52 µs → ~0.74 µs
  • m_translationSpecs made volatile for the reload race

Per trap on the shipped link-down config: 6 DB round trips → 3, regex compilations → 0.

Assisted by Anthropic Claude Opus 5.

External References

EventTranslatorConfigFactory repeated most of its work on every event.

Value specs exposed matches() and getResult() as separate calls, and
TranslationMapping.translate() invoked both, so each value was resolved
twice per event. For a sql value that meant two connection checkouts,
two prepared statements and two round trips, and nested values were
evaluated three times. ValueSpec now exposes a single evaluate() that
returns whether the value matched along with the value to assign.
EvaluationResult carries the two separately rather than collapsing into
an Optional, because a sql lookup that finds a row with a null column is
a match whose value is null, which must not fall through to the
assignment default.

The matches regex was recompiled on every evaluation, and a "~"-prefixed
parameter name was recompiled once per parm scanned via String.matches.
Both are now compiled once when the value spec is constructed.

translate() cloned the event before running any assignment, so a mapping
that rejected the event still paid for the clone. Assignments are now
resolved against the source event first, which is safe because value
specs only ever read the source event, and the clone happens only once
the mapping is known to match. The early exit on the first assignment
that neither matches nor has a default is preserved, so a rejecting
mapping does no more work than before.

cloneEvent() deep-copied through a Java serialization round trip, which
spent most of its time re-writing class descriptors: 52 us/op against
0.74 us/op for a field copy through the immutable event model. Event
does not implement IEvent, so the copy goes via ImmutableMapper. Both
mappers cover all 34 of Event's fields.

m_translationSpecs is now volatile, since update() clears it while
translateEvent() reads it without synchronization.

No configuration, schema or interface changes.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR reduces per-event overhead in EventTranslatorConfigFactory by avoiding duplicate work during translation (notably repeated SQL queries, repeated regex compilation, and unnecessary cloning), and adds focused regression tests for SQL translation semantics and event cloning fidelity.

Changes:

  • Refactors translation evaluation to compute “match + value” once per ValueSpec evaluation (avoids double SQL round trips) and delays cloning until after a mapping matches.
  • Compiles matches patterns and ~ parameter-name regexes once per spec construction rather than per event.
  • Replaces serialization-based cloneEvent() with a deep copy via the immutable event model; adds new tests covering SQL-value behavior and clone fidelity.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
opennms-config/src/main/java/org/opennms/netmgt/config/EventTranslatorConfigFactory.java Core translator refactor for single-pass evaluation, regex precompilation, delayed cloning, and new cloning implementation.
opennms-config/src/test/java/org/opennms/netmgt/config/EventTranslatorSqlValueTest.java Adds tests ensuring SQL value evaluation issues only one query per event and distinguishes “no row” vs “null column”.
opennms-config/src/test/java/org/opennms/netmgt/config/EventTranslatorCloneEventTest.java Adds tests to ensure cloneEvent() preserves fields and is deep enough for independent mutation.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Read m_translationSpecs into a local before the null check. Returning the
field directly hands back null when update() clears it in between, and
translateEvent() iterates the result. Two threads racing a reload may now
each construct a list, which is cheaper than putting a lock on the
per-event path.

Fix the misplaced quotes in the two getAttributeValue() debug messages.

@christianpape christianpape left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM.

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.

3 participants