Skip to content

Commit fafeff0

Browse files
committed
dedup
1 parent e56f0ff commit fafeff0

File tree

4 files changed

+46
-8
lines changed

4 files changed

+46
-8
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ Processor flags:
181181
- `false`: report only first-seen stack hashes within the current dedup window
182182
- `processor.stackHashResetIntervalMillis`
183183
- Periodically clears remembered stack hashes to cap memory usage in long-running JVMs
184-
- Default: `300000` (5 minutes)
184+
- In dedup mode (`reportAllStacks: false`): if missing, JCT logs a warning and uses `30000` (30 seconds)
185185

186186
Example: report only new stacks (good for high-traffic legacy systems)
187187

src/main/java/de/marcelsauer/profiler/config/Processor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ public class Processor {
1616

1717
/**
1818
* reset interval for remembered stack hashes in dedup mode to cap memory usage
19+
* null means not explicitly configured
1920
*/
20-
public long stackHashResetIntervalMillis = 300_000L;
21+
public Long stackHashResetIntervalMillis;
2122

2223
public String udpHost = "localhost";
2324
public int udpPort = 9999;

src/main/java/de/marcelsauer/profiler/processor/AbstractAsyncStackProcessor.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ public abstract class AbstractAsyncStackProcessor implements StackProcessor {
2121
private static final String JCA_PROCESSOR_THREAD = "jca-processor-thread";
2222
private static final int CAPACITY = 100_000;
2323
private static final int DRAIN_BATCH_SIZE = 2048;
24+
private static final long DEFAULT_STACK_HASH_RESET_INTERVAL_MILLIS = 300_000L;
25+
private static final long DEFAULT_STACK_HASH_RESET_INTERVAL_IN_DEDUP_MODE_MILLIS = 30_000L;
2426

2527
/**
2628
* counters
@@ -34,6 +36,7 @@ public abstract class AbstractAsyncStackProcessor implements StackProcessor {
3436
private final List<RecordingEvent> dedupBuffer = new ArrayList<>(DRAIN_BATCH_SIZE);
3537
private final Set<Integer> seenStackHashes = new HashSet<>();
3638
private long nextStackHashResetAtMillis = 0L;
39+
private boolean warnedMissingDedupResetInterval;
3740

3841
/**
3942
* acting like cron
@@ -177,7 +180,24 @@ protected boolean isReportAllStacks() {
177180
}
178181

179182
protected long getStackHashResetIntervalMillis() {
180-
return Math.max(1_000L, Config.get().processor.stackHashResetIntervalMillis);
183+
Long configuredInterval = getConfiguredStackHashResetIntervalMillis();
184+
if (configuredInterval != null) {
185+
return Math.max(1_000L, configuredInterval);
186+
}
187+
188+
if (!isReportAllStacks()) {
189+
if (!warnedMissingDedupResetInterval) {
190+
logger.warn("processor.stackHashResetIntervalMillis is not set while processor.reportAllStacks=false. using default 30000ms");
191+
warnedMissingDedupResetInterval = true;
192+
}
193+
return DEFAULT_STACK_HASH_RESET_INTERVAL_IN_DEDUP_MODE_MILLIS;
194+
}
195+
196+
return DEFAULT_STACK_HASH_RESET_INTERVAL_MILLIS;
197+
}
198+
199+
protected Long getConfiguredStackHashResetIntervalMillis() {
200+
return Config.get().processor.stackHashResetIntervalMillis;
181201
}
182202

183203
protected long currentTimeMillis() {

src/test/java/de/marcelsauer/profiler/processor/AbstractAsyncStackProcessorTest.java

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,31 @@ public void thatSeenHashesAreResetAfterConfiguredInterval() throws InterruptedEx
7575
assertEquals(2, processor.getProcessedCount());
7676
}
7777

78+
@Test
79+
public void thatMissingDedupIntervalFallsBackToThirtySeconds() throws InterruptedException {
80+
TestProcessor processor = new TestProcessor(false, null);
81+
processor.start();
82+
83+
processor.process(newEvent("m1"));
84+
Thread.sleep(1200L);
85+
86+
processor.advanceClockMillis(31_000L);
87+
processor.process(newEvent("m1"));
88+
Thread.sleep(1200L);
89+
90+
processor.stop();
91+
92+
assertEquals(2, processor.getProcessedCount());
93+
}
94+
7895
private RecordingEvent newEvent(String methodName) {
7996
Stack.StackEntry entry = new Stack.StackEntry(methodName, 1L, 0);
8097
return new RecordingEvent(new Stack(Collections.singletonList(entry)));
8198
}
8299

83100
private static class TestProcessor extends AbstractAsyncStackProcessor {
84101
private final boolean reportAllStacks;
85-
private final long stackHashResetIntervalMillis;
102+
private final Long configuredStackHashResetIntervalMillis;
86103
private long nowMillis;
87104
private final AtomicInteger processedCount = new AtomicInteger();
88105
private final List<Integer> batchSizes = Collections.synchronizedList(new ArrayList<Integer>());
@@ -91,9 +108,9 @@ private static class TestProcessor extends AbstractAsyncStackProcessor {
91108
this(true, 300_000L);
92109
}
93110

94-
TestProcessor(boolean reportAllStacks, long stackHashResetIntervalMillis) {
111+
TestProcessor(boolean reportAllStacks, Long stackHashResetIntervalMillis) {
95112
this.reportAllStacks = reportAllStacks;
96-
this.stackHashResetIntervalMillis = stackHashResetIntervalMillis;
113+
this.configuredStackHashResetIntervalMillis = stackHashResetIntervalMillis;
97114
}
98115

99116
@Override
@@ -118,8 +135,8 @@ protected boolean isReportAllStacks() {
118135
}
119136

120137
@Override
121-
protected long getStackHashResetIntervalMillis() {
122-
return stackHashResetIntervalMillis;
138+
protected Long getConfiguredStackHashResetIntervalMillis() {
139+
return configuredStackHashResetIntervalMillis;
123140
}
124141

125142
@Override

0 commit comments

Comments
 (0)