@Override
        public void run() {
          long currentTime = System.currentTimeMillis();

          for (Iterator<Map.Entry<String, Long>> it = metricsMap.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry<String, Long> metricEntry = it.next();
            String metricName = metricEntry.getKey();
            if (!acceptMetric(metricName)) {
              it.remove();
            }
          }
          final List<SingleMetric> metrics = new ArrayList<>();
          for (String metricName : metricsMap.keySet()) {
            double value = metricsMap.get(metricName).doubleValue();
            metrics.add(new SingleMetric(metricName, value, currentTime));

            /*
             * Add computed (Timer/Counter) metric.
             * Example
             * Counter Metric : Counter.ReadAllQuery.HostRoleCommandEntity = 10000
             * Timer Metric : Timer.ReadAllQuery.HostRoleCommandEntity = 50
             * Computed Metric (Avg time for the operation) : ReadAllQuery.HostRoleCommandEntity = 200 (10000 div by 50)
             */

            if (metricName.startsWith(COUNTER)) {
              String baseMetricName = metricName.substring(COUNTER.length());
              if (metricsMap.containsKey(TIMER + baseMetricName)) {
                double timerValue = metricsMap.get(TIMER + baseMetricName).doubleValue();
                if (value != 0.0) {
                  metrics.add(new SingleMetric(baseMetricName, timerValue / value , currentTime));
                }
              }
            }
          }
          sink.publish(metrics);
        }
Method to publish metrics to Sink asynchronously.
@param metricsMap Map of metrics to be published to Sink
ambari-server/src/main/java/org/apache/ambari/server/metrics/system/impl/DatabaseMetricsSource.java