From 66af24e6071b2f8ada7bbeef77e00bce3fe48e8f Mon Sep 17 00:00:00 2001 From: Elliott Clark Date: Mon, 26 Nov 2012 11:35:47 -0800 Subject: [PATCH] Move the cache buster to be async --- .../hadoop/metrics2/impl/JmxCacheBuster.java | 39 +++++++++++++---- .../hadoop/metrics2/impl/JmxCacheBuster.java | 44 +++++++++++++++----- 2 files changed, 64 insertions(+), 19 deletions(-) diff --git hbase-hadoop1-compat/src/main/java/org/apache/hadoop/metrics2/impl/JmxCacheBuster.java hbase-hadoop1-compat/src/main/java/org/apache/hadoop/metrics2/impl/JmxCacheBuster.java index 1e2eb2f..741449c 100644 --- hbase-hadoop1-compat/src/main/java/org/apache/hadoop/metrics2/impl/JmxCacheBuster.java +++ hbase-hadoop1-compat/src/main/java/org/apache/hadoop/metrics2/impl/JmxCacheBuster.java @@ -20,7 +20,13 @@ package org.apache.hadoop.metrics2.impl; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.metrics2.MetricsExecutor; import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem; +import org.apache.hadoop.metrics2.lib.MetricsExecutorImpl; + + +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; /** * JMX caches the beans that have been exported; even after the values are removed from hadoop's @@ -32,21 +38,38 @@ import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem; */ public class JmxCacheBuster { private static final Log LOG = LogFactory.getLog(JmxCacheBuster.class); + private static Object lock = new Object(); + private static ScheduledFuture fut = null; + private static MetricsExecutor executor = new MetricsExecutorImpl(); /** * For JMX to forget about all previously exported metrics. */ public static void clearJmxCache() { - LOG.trace("Clearing JMX mbean cache."); - // This is pretty extreme but it's the best way that - // I could find to get metrics to be removed. + //If there are more then 100 ms before the executor will run then everything should be merged. + if (fut == null || (!fut.isDone() && fut.getDelay(TimeUnit.MILLISECONDS) > 100)) return; + + synchronized (lock) { + fut = executor.getExecutor().schedule(new JmxCacheBusterRunnable(), 5, TimeUnit.SECONDS); + } + } + + static class JmxCacheBusterRunnable implements Runnable { + + @Override + public void run() { + LOG.trace("Clearing JMX mbean cache."); + + // This is pretty extreme but it's the best way that + // I could find to get metrics to be removed. - try { - DefaultMetricsSystem.INSTANCE.stop(); - DefaultMetricsSystem.INSTANCE.start(); - } catch (Exception exception ) { - LOG.debug("error clearing the jmx it appears the metrics system hasn't been started", exception); + try { + DefaultMetricsSystem.INSTANCE.stop(); + DefaultMetricsSystem.INSTANCE.start(); + } catch (Exception exception ) { + LOG.debug("error clearing the jmx it appears the metrics system hasn't been started", exception); + } } } } diff --git hbase-hadoop2-compat/src/main/java/org/apache/hadoop/metrics2/impl/JmxCacheBuster.java hbase-hadoop2-compat/src/main/java/org/apache/hadoop/metrics2/impl/JmxCacheBuster.java index ce5b9e2..9fa9fa1 100644 --- hbase-hadoop2-compat/src/main/java/org/apache/hadoop/metrics2/impl/JmxCacheBuster.java +++ hbase-hadoop2-compat/src/main/java/org/apache/hadoop/metrics2/impl/JmxCacheBuster.java @@ -20,7 +20,12 @@ package org.apache.hadoop.metrics2.impl; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.metrics2.MetricsExecutor; import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem; +import org.apache.hadoop.metrics2.lib.MetricsExecutorImpl; + +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; /** * JMX caches the beans that have been exported; even after the values are removed from hadoop's @@ -32,23 +37,40 @@ import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem; */ public class JmxCacheBuster { private static final Log LOG = LogFactory.getLog(JmxCacheBuster.class); + private static Object lock = new Object(); + private static ScheduledFuture fut = null; + private static MetricsExecutor executor = new MetricsExecutorImpl(); /** * For JMX to forget about all previously exported metrics. */ public static void clearJmxCache() { - LOG.trace("Clearing JMX mbean cache."); - - // This is pretty extreme but it's the best way that - // I could find to get metrics to be removed. - try { - if (DefaultMetricsSystem.instance() != null ) { - DefaultMetricsSystem.instance().stop(); - DefaultMetricsSystem.instance().start(); - } - } catch (Exception exception ) { - LOG.debug("error clearing the jmx it appears the metrics system hasn't been started", exception); + //If there are more then 100 ms before the executor will run then everything should be merged. + if (fut == null || (!fut.isDone() && fut.getDelay(TimeUnit.MILLISECONDS) > 100)) return; + + synchronized (lock) { + fut = executor.getExecutor().schedule(new JmxCacheBusterRunnable(), 5, TimeUnit.SECONDS); + } + } + + static class JmxCacheBusterRunnable implements Runnable { + + @Override + public void run() { + LOG.trace("Clearing JMX mbean cache."); + + // This is pretty extreme but it's the best way that + // I could find to get metrics to be removed. + try { + if (DefaultMetricsSystem.instance() != null ) { + DefaultMetricsSystem.instance().stop(); + DefaultMetricsSystem.instance().start(); + } + + } catch (Exception exception ) { + LOG.debug("error clearing the jmx it appears the metrics system hasn't been started", exception); + } } } } -- 1.7.10.2 (Apple Git-33)