fix(attribution): one active attribution runtime per JVM #11

Merged
KofTwentyTwo merged 1 commits from fix/single-attribution-runtime into develop 2026-10-15 22:09:56 +00:00
3 changed files with 32 additions and 0 deletions

No files matched your search

+1
View File
@@ -5,6 +5,7 @@ All notable changes are documented here. This project follows Keep a Changelog a
## [Unreleased]
### Fixed
- Only one runtime attributes per JVM: starting attribution on a newer instance (a hot swap, or repeated server starts in tests) stops the previous one, so old instances are never pinned by a forgotten listener and flusher.
- Each table has its own icon (the app icon is now `storage`), so nav entries are distinguishable and do not repeat icons used elsewhere.
- Home tables keep at most four columns with plain headers (readable at every width): secondary facts such as calls and mean time, the session's query text, and a unit's kind and top table move into a second line of the first cell.
@@ -42,6 +42,12 @@ public class DbPerfRuntime implements QSupplementalInstanceMetaData
private final DbPerfQBitConfig config;
private AttributionFlusher attributionFlusher;
/////////////////////////////////////////////////////////////////////////////
// statement listeners are JVM-wide: only one runtime attributes at a time //
// (a newer instance, e.g. after a hot swap or in tests, replaces the old) //
/////////////////////////////////////////////////////////////////////////////
private static final AtomicReference<DbPerfRuntime> ACTIVE_ATTRIBUTION = new AtomicReference<>();
/*******************************************************************************
** Runtime bound to a single host instance.
@@ -149,6 +155,11 @@ public class DbPerfRuntime implements QSupplementalInstanceMetaData
{
if(attributionFlusher == null && Boolean.TRUE.equals(config.getAttributionEnabled()))
{
DbPerfRuntime previous = ACTIVE_ATTRIBUTION.getAndSet(this);
if(previous != null && previous != this)
{
previous.stopAttribution();
}
attributionFlusher = new AttributionFlusher(this);
attributionFlusher.start();
}
@@ -160,6 +171,7 @@ public class DbPerfRuntime implements QSupplementalInstanceMetaData
*******************************************************************************/
public synchronized void stopAttribution()
{
ACTIVE_ATTRIBUTION.compareAndSet(this, null);
if(attributionFlusher != null)
{
attributionFlusher.close();
@@ -569,6 +569,25 @@ class AttributionTest
}
/*******************************************************************************
** Only one runtime attributes per JVM: starting another stops the first, so
** repeated server starts (tests, hot swaps) never pile up listeners.
*******************************************************************************/
@Test
void oneActiveRuntime() throws Exception
{
StatementExecutionListeners.unregister(listener);
runtime.startAttribution();
DbPerfRuntime other = new DbPerfRuntime(runtime.getInstance(), runtime.getConfig());
other.startAttribution();
runtime.stopAttribution();
assertThat(StatementExecutionListeners.isActive()).isTrue();
other.stopAttribution();
assertThat(StatementExecutionListeners.isActive()).isFalse();
}
/*******************************************************************************
** Deliver a statement with exact counter values.
*******************************************************************************/