|
58 | 58 | import java.util.Enumeration;
|
59 | 59 | import java.util.HashMap;
|
60 | 60 | import java.util.HashSet;
|
| 61 | +import java.util.Iterator; |
61 | 62 | import java.util.Map;
|
62 | 63 | import java.util.Set;
|
63 | 64 | import java.util.concurrent.atomic.AtomicInteger;
|
@@ -345,21 +346,30 @@ public void propertyChange(PropertyChangeEvent evt) {
|
345 | 346 | private static final int HEARTBEAT_THREADS = 10;
|
346 | 347 | private final Set<JmxApplication> unavailableApps = new HashSet();
|
347 | 348 |
|
| 349 | + private volatile boolean heartbeatRunning; |
| 350 | + private volatile boolean anotherHeartbeatPending; |
| 351 | + |
348 | 352 | 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 | + } |
351 | 359 |
|
352 | 360 | Set<JmxApplication> apps = new HashSet();
|
353 | 361 | synchronized (unavailableApps) {
|
354 | 362 | apps.addAll(unavailableApps);
|
355 | 363 | unavailableApps.clear();
|
356 | 364 | }
|
357 | 365 |
|
| 366 | + Iterator<JmxApplication> appsI = apps.iterator(); |
| 367 | + while (appsI.hasNext()) if (appsI.next().isRemoved()) appsI.remove(); |
358 | 368 | if (apps.isEmpty()) return;
|
359 | 369 |
|
360 | 370 | final AtomicInteger counter = new AtomicInteger(apps.size());
|
361 | 371 | 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()); |
363 | 373 | for (final JmxApplication app : apps) {
|
364 | 374 | processor.post(new Runnable() {
|
365 | 375 | @Override
|
@@ -395,8 +405,18 @@ public void propertyChange(PropertyChangeEvent evt) {
|
395 | 405 | }
|
396 | 406 |
|
397 | 407 | 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 |
400 | 420 | }
|
401 | 421 | }
|
402 | 422 | }, HEARTBEAT_POLL);
|
|
0 commit comments