@@ -217,10 +217,19 @@ public JmxApplication createJmxApplication(String connectionString, String displ
217
217
throw new JmxApplicationException (e .getMessage (), e .getCause ());
218
218
}
219
219
}
220
-
220
+
221
221
private JmxApplication addJmxApplication (boolean newApp , JMXServiceURL serviceURL ,
222
222
String connectionName , String displayName , String suggestedName , String hostName ,
223
- EnvironmentProvider provider , Storage storage , String allowsInsecure , boolean lazyCheck ) throws JMXException {
223
+ EnvironmentProvider provider , Storage storage , String allowsInsecure , boolean lazy ) throws JMXException {
224
+
225
+ if (lazy ) return addLazyJmxApplication (newApp , serviceURL , connectionName , displayName , suggestedName ,
226
+ hostName , provider , storage , allowsInsecure , true );
227
+ else throw new RuntimeException ("Only lazy JMX connections currently implemented!" ); // NOI18N
228
+ }
229
+
230
+ private JmxApplication addLazyJmxApplication (boolean newApp , JMXServiceURL serviceURL , String connectionName ,
231
+ String displayName , String suggestedName , String hostName , EnvironmentProvider provider ,
232
+ Storage storage , String allowsInsecure , boolean scheduleHeartbeat ) throws JMXException {
224
233
225
234
// Resolve JMXServiceURL, finish if not resolved
226
235
if (serviceURL == null ) {
@@ -300,8 +309,8 @@ private JmxApplication addJmxApplication(boolean newApp, JMXServiceURL serviceUR
300
309
// Setup whether the SSL connection is required or not
301
310
application .getStorage ().setCustomProperty (PROPERTY_RETRY_WITHOUT_SSL , allowsInsecure );
302
311
303
- // NOTE: 'lazyCheck' currently always true!
304
-
312
+ // // NOTE: 'lazyCheck' currently always true!
313
+ //
305
314
// // Connect to the JMX agent
306
315
// JmxModel model = lazyCheck ? null : JmxModelFactory.getJmxModelFor(application);
307
316
//
@@ -337,21 +346,26 @@ private JmxApplication addJmxApplication(boolean newApp, JMXServiceURL serviceUR
337
346
338
347
// if (model == null || model.getConnectionState() != ConnectionState.CONNECTED) {
339
348
synchronized (unavailableApps ) { unavailableApps .add (application ); }
340
- scheduleHeartbeat ();
349
+ if ( scheduleHeartbeat ) scheduleHeartbeat ();
341
350
// }
342
351
343
352
return application ;
344
353
}
345
354
346
355
347
- private static final int HEARTBEAT_POLL = 5000 ;
348
- private static final int HEARTBEAT_THREADS = 10 ;
356
+ private static final int HEARTBEAT_DELAY = 100 ;
357
+ private static final int HEARTBEAT_POLL_DELAY = 5000 ;
358
+ private static final int HEARTBEAT_MAX_THREADS = 10 ;
349
359
private final Set <JmxApplication > unavailableApps = new HashSet ();
350
360
351
361
private volatile boolean heartbeatRunning ;
352
362
private volatile boolean anotherHeartbeatPending ;
353
363
354
364
private void scheduleHeartbeat () {
365
+ scheduleHeartbeatImpl (true );
366
+ }
367
+
368
+ private void scheduleHeartbeatImpl (boolean immediately ) {
355
369
if (heartbeatRunning ) {
356
370
anotherHeartbeatPending = true ;
357
371
return ;
@@ -373,53 +387,55 @@ private void scheduleHeartbeat() {
373
387
}
374
388
375
389
final AtomicInteger counter = new AtomicInteger (apps .size ());
376
- final RequestProcessor processor = new RequestProcessor ("JMX Heartbeat Processor" , Math .min (counter .intValue (), HEARTBEAT_THREADS )); // NOI18N
377
- // System.err.println(">>> Heartbeat for " + counter + " targets at " + LocalTime.now());
390
+ RequestProcessor processor = new RequestProcessor ("JMX Heartbeat Processor" , Math .min (counter .intValue (), HEARTBEAT_MAX_THREADS )); // NOI18N
391
+ // System.err.println(">>> Heartbeat for " + counter + " targets at " + java.time. LocalTime.now());
378
392
for (final JmxApplication app : apps ) {
379
393
processor .post (new Runnable () {
380
394
@ Override
381
395
public void run () {
382
- JmxModel model = new JmxModelProvider ().createModelFor (app );
383
- if (model == null || model .getConnectionState () != ConnectionState .CONNECTED ) {
384
- synchronized (unavailableApps ) { unavailableApps .add (app ); }
385
- } else {
386
- app .setStateImpl (Stateful .STATE_AVAILABLE );
387
-
388
- app .jmxModel = JmxModelFactory .getJmxModelFor (app );
389
- app .jvm = JvmFactory .getJVMFor (app );
390
-
391
- app .jmxModel .addPropertyChangeListener (new PropertyChangeListener () {
392
- public void propertyChange (PropertyChangeEvent evt ) {
393
- if (evt .getNewValue () == ConnectionState .CONNECTED ) {
394
- app .setStateImpl (Stateful .STATE_AVAILABLE );
395
- } else {
396
- app .setStateImpl (Stateful .STATE_UNAVAILABLE );
397
- if (!app .isRemoved ()) {
398
- synchronized (unavailableApps ) { unavailableApps .add (app ); }
399
- scheduleHeartbeat ();
396
+ try {
397
+ JmxModel model = new JmxModelProvider ().createModelFor (app );
398
+ if (model == null || model .getConnectionState () != ConnectionState .CONNECTED ) {
399
+ synchronized (unavailableApps ) { unavailableApps .add (app ); }
400
+ } else {
401
+ app .setStateImpl (Stateful .STATE_AVAILABLE );
402
+
403
+ app .jmxModel = JmxModelFactory .getJmxModelFor (app );
404
+ app .jvm = JvmFactory .getJVMFor (app );
405
+
406
+ app .jmxModel .addPropertyChangeListener (new PropertyChangeListener () {
407
+ public void propertyChange (PropertyChangeEvent evt ) {
408
+ if (evt .getNewValue () == ConnectionState .CONNECTED ) {
409
+ app .setStateImpl (Stateful .STATE_AVAILABLE );
410
+ } else {
411
+ app .setStateImpl (Stateful .STATE_UNAVAILABLE );
412
+ if (!app .isRemoved ()) {
413
+ synchronized (unavailableApps ) { unavailableApps .add (app ); }
414
+ scheduleHeartbeatImpl (true );
415
+ }
416
+ // TODO: remove listener from model once not needed!
400
417
}
401
- // TODO: remove listener from model once not needed!
418
+ }
419
+ });
420
+ }
421
+ } finally {
422
+ if (counter .decrementAndGet () == 0 ) {
423
+ heartbeatRunning = false ; // done
424
+
425
+ if (!anotherHeartbeatPending ) {
426
+ anotherHeartbeatPending = false ;
427
+ synchronized (unavailableApps ) {
428
+ Iterator <JmxApplication > appsI = unavailableApps .iterator ();
429
+ while (appsI .hasNext ()) if (appsI .next ().isRemoved ()) appsI .remove ();
430
+ if (unavailableApps .isEmpty ()) return ; // not pending and no apps to check, return
402
431
}
403
432
}
404
- });
405
- }
406
-
407
- if (counter .decrementAndGet () == 0 ) {
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
- }
433
+
434
+ if (!heartbeatRunning ) scheduleHeartbeatImpl (false ); // start again if needed and not running yet
417
435
}
418
-
419
- if (!heartbeatRunning ) scheduleHeartbeat (); // start again if needed and not running yet
420
436
}
421
437
}
422
- }, HEARTBEAT_POLL );
438
+ }, immediately ? HEARTBEAT_DELAY : HEARTBEAT_POLL_DELAY );
423
439
}
424
440
}
425
441
@@ -513,7 +529,8 @@ public synchronized void dataChanged(DataChangeEvent<Host> event) {
513
529
for (Host host : hosts ) {
514
530
String hostName = host .getHostName ();
515
531
Set <Storage > storageSet = persistedApplications .get (hostName );
516
- if (storageSet != null ) {
532
+ int storageSetSize = storageSet == null ? 0 : storageSet .size ();
533
+ if (storageSetSize > 0 ) {
517
534
persistedApplications .remove (hostName );
518
535
519
536
String [] keys = new String [] {
@@ -524,10 +541,13 @@ public synchronized void dataChanged(DataChangeEvent<Host> event) {
524
541
PROPERTY_ENV_PROVIDER_ID ,
525
542
PROPERTY_RETRY_WITHOUT_SSL
526
543
};
544
+
545
+ final AtomicInteger counter = new AtomicInteger (storageSetSize );
546
+ RequestProcessor processor = new RequestProcessor ("JMX Persistence Processor" , Math .min (counter .intValue (), HEARTBEAT_MAX_THREADS )); // NOI18N
527
547
528
548
for (final Storage storage : storageSet ) {
529
549
final String [] values = storage .getCustomProperties (keys );
530
- new RequestProcessor () .post (new Runnable () {
550
+ processor .post (new Runnable () {
531
551
public void run () {
532
552
try {
533
553
String epid = values [4 ];
@@ -539,8 +559,8 @@ public void run() {
539
559
EnvironmentProvider ep = epid == null ? null :
540
560
JmxConnectionSupportImpl .
541
561
getProvider (epid );
542
- addJmxApplication (false , null , values [0 ], values [2 ], values [3 ],
543
- values [1 ], ep , storage , values [5 ], true );
562
+ addLazyJmxApplication (false , null , values [0 ], values [2 ], values [3 ],
563
+ values [1 ], ep , storage , values [5 ], false );
544
564
} catch (final JMXException e ) {
545
565
if (e .isConfig ()) {
546
566
DialogDisplayer .getDefault ().notifyLater (
@@ -553,6 +573,8 @@ public void run() {
553
573
failedAppsN .add (name );
554
574
failedAppsS .add (storage );
555
575
}
576
+ } finally {
577
+ if (counter .decrementAndGet () == 0 ) scheduleHeartbeat ();
556
578
}
557
579
synchronized (persistedAppsCount ) {
558
580
persistedAppsCount [0 ]--;
0 commit comments