Skip to content

Commit 2e91620

Browse files
committed
Prototype of JMX heartbeat synchronization, cleanup removed JMX applications
1 parent 1946f4a commit 2e91620

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

visualvm/jmx/src/org/graalvm/visualvm/jmx/impl/JmxApplicationProvider.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
import java.util.Enumeration;
5959
import java.util.HashMap;
6060
import java.util.HashSet;
61+
import java.util.Iterator;
6162
import java.util.Map;
6263
import java.util.Set;
6364
import java.util.concurrent.atomic.AtomicInteger;
@@ -345,21 +346,30 @@ public void propertyChange(PropertyChangeEvent evt) {
345346
private static final int HEARTBEAT_THREADS = 10;
346347
private final Set<JmxApplication> unavailableApps = new HashSet();
347348

349+
private volatile boolean heartbeatRunning;
350+
private volatile boolean anotherHeartbeatPending;
351+
348352
private void scheduleHeartbeat() {
349-
// NOTE: should not run in parallel if already running
350-
// should be instead restarted when the current run finished
353+
if (heartbeatRunning) {
354+
anotherHeartbeatPending = true;
355+
return;
356+
} else {
357+
heartbeatRunning = true;
358+
}
351359

352360
Set<JmxApplication> apps = new HashSet();
353361
synchronized (unavailableApps) {
354362
apps.addAll(unavailableApps);
355363
unavailableApps.clear();
356364
}
357365

366+
Iterator<JmxApplication> appsI = apps.iterator();
367+
while (appsI.hasNext()) if (appsI.next().isRemoved()) appsI.remove();
358368
if (apps.isEmpty()) return;
359369

360370
final AtomicInteger counter = new AtomicInteger(apps.size());
361371
final RequestProcessor processor = new RequestProcessor("JMX Heartbeat Processor", Math.min(counter.intValue(), HEARTBEAT_THREADS)); // NOI18N
362-
372+
// System.err.println(">>> Heartbeat for " + counter + " targets at " + LocalTime.now());
363373
for (final JmxApplication app : apps) {
364374
processor.post(new Runnable() {
365375
@Override
@@ -395,8 +405,18 @@ public void propertyChange(PropertyChangeEvent evt) {
395405
}
396406

397407
if (counter.decrementAndGet() == 0) {
398-
synchronized (unavailableApps) { if (unavailableApps.isEmpty()) return; }
399-
scheduleHeartbeat();
408+
heartbeatRunning = false; // done
409+
410+
if (!anotherHeartbeatPending) {
411+
anotherHeartbeatPending = false;
412+
synchronized (unavailableApps) {
413+
Iterator<JmxApplication> appsI = unavailableApps.iterator();
414+
while (appsI.hasNext()) if (appsI.next().isRemoved()) appsI.remove();
415+
if (unavailableApps.isEmpty()) return; // not pending and no apps to check, return
416+
}
417+
}
418+
419+
if (!heartbeatRunning) scheduleHeartbeat(); // start again if needed and not running yet
400420
}
401421
}
402422
}, HEARTBEAT_POLL);

0 commit comments

Comments
 (0)