@ PreDestroy public void stop ( ) { logger . info ( "Stop..." ) ; lifecycleLock . writeLock ( ) . lock ( ) ; try { if ( ! State . STARTED . equals ( state ) ) { logger . debug ( "Ignore stop() command for " + state + " instance" ) ; return ; } logger . info ( "Unregister shutdown hook" ) ; this . shutdownHook . unregisterFromRuntime ( ) ; logger . info ( "Shutdown collectScheduledExecutor and exportScheduledExecutor..." ) ; // no need to `shutdown()` and `awaitTermination()` before `shutdownNow()` as we invoke `collectMetrics()` and `exportCollectedMetrics()` // `shutdownNow()` can be invoked before `collectMetrics()` and `exportCollectedMetrics()` collectScheduledExecutor . shutdownNow ( ) ; exportScheduledExecutor . shutdownNow ( ) ; try { logger . info ( "Collect metrics..." ) ; collectMetrics ( ) ; logger . info ( "Export metrics..." ) ; exportCollectedMetrics ( ) ; } catch ( RuntimeException e ) { logger . warn ( "Ignore failure collecting and exporting metrics during stop" , e ) ; } // queries and outputwriters can be stopped even if exports threads are running thanks to the lifecycleLock logger . info ( "Stop queries..." ) ; for ( Query query : queries ) { try { query . stop ( ) ; } catch ( Exception e ) { logger . warn ( "Ignore exception stopping query {}" , query , e ) ; } } logger . info ( "Stop output writers..." ) ; for ( OutputWriter outputWriter : outputWriters ) { try { outputWriter . stop ( ) ; } catch ( Exception e ) { logger . warn ( "Ignore exception stopping outputWriters" , e ) ; } } state = State . STOPPED ; logger . info ( "Set state to {}" , state ) ; } catch ( RuntimeException e ) { state = State . ERROR ; if ( logger . isDebugEnabled ( ) ) { // to troubleshoot JMX call errors or equivalent, it may be useful to log and rethrow logger . warn ( "Exception stopping EmbeddedJmxTrans" , e ) ; } throw e ; } finally { lifecycleLock . writeLock ( ) . unlock ( ) ; } logger . info ( "Stopped" ) ; }
Stop scheduled executors and collect - and - export metrics one last time .