NMS-19573: Creating metadata cache - #8331
Conversation
christianpape
commented
Mar 3, 2026
- JIRA: https://opennms.atlassian.net/browse/NMS-19573
f1064bc to
e0d66a9
Compare
|
I updated the title to fix the typo on the NMS issue, just FYI. I'm reviewing this one now. |
marshallmassengill
left a comment
There was a problem hiding this comment.
A few things for the review:
There are some updates for F2024 that will make it so this doesn't build as it is.
Something to check is where this is wired in. I think Core gets this from Spring (applicationContext-entity-scope-provider.xml declares plain EntityScopeProviderImpl as the primary bean). Suggestion from Claude here:
The cache belongs at the Spring primary bean, where it also helps pollerd's residual per-poll builds after NMS-20009 and collectd's per-cycle parameter interpolation. Also, look at NMS-20007, where thresholding will build at most one scope per service per cycle.
It's got unbounded caches of Hibernate entity graphs by default. Default maximumSize=-1 means four unbounded caches, each value an ObjectScope pinning a loaded node, its ~60-field asset record, and metadata collections for a rolling 10 minutes. This should probably be a bounded default, and ideally the cached value should be a materialized MapScope snapshot rather than entity-wrapping scopes to also remove the detached-lazy-proxy hazard.
EntityScopeProviderImpl.getScopeForNode(null) returns EmptyScope.EMPTY; the decorator calls nodeScopes.getUnchecked(null) and Guava throws NPE on null key.
CachedEntityScopeProviderIT extends EntityScopeProviderIT and constructs the decorator with expireAfterWrite=0 — immediate expiry, caching effectively disabled. It proves delegation preserves semantics, which is worth having, but the suite passes even if the cache never caches. This is missing a second-lookup-doesn't-invoke-the-loader test, expiry behavior, and the null-key case.
refreshAfterWrite without an async reload() override refreshes synchronously on the caller's thread — the knob implies more than it delivers.
No recordStats()/metrics for what is explicitly a performance feature, so field hit-rates are unobservable.
maximumSize=0 also means unbounded (> 0 check) — doc trap.
Check the license header.
e0d66a9 to
4e5da67
Compare
marshallmassengill
left a comment
There was a problem hiding this comment.
Not sure if this is intentional but the cfg file only tunes the blueprint instance; the Spring instance (Collectd, poller client, core thresholding) is hardcoded 900s and can't be disabled.
These seem like they are worth looking at:
- refreshAfterWrite=0 throws at construction (Guava requires > 0; guard is >= 0).
- testCache is timing-sensitive (5s window across DB saves) — a Ticker constructor arg would make it deterministic.
We also may want to put something in the release notes since this is a behavior change I would think.
cgorantla
left a comment
There was a problem hiding this comment.
This probably can be termed as metadata cache for all components not just for Thresholding.
| </bean> | ||
|
|
||
|
|
||
| <cm:property-placeholder id="org.opennms.netmgt.threshd.metadata.cache" |
There was a problem hiding this comment.
This is only relevant in Sentinel