All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.netflix.spectator.api.patterns.GaugePoller Maven / Gradle / Ivy

There is a newer version: 1.7.21
Show newest version
/*
 * Copyright 2014-2017 Netflix, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.netflix.spectator.api.patterns;

import java.lang.ref.WeakReference;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;

/**
 * Helper for polling gauges in a background thread. A shared executor is used with a
 * single thread. If registered gauge methods are cheap as they should be, then this
 * should be plenty of capacity to process everything regularly. If not, then this will
 * help limit the damage to a single core and avoid causing problems for the application.
 */
final class GaugePoller {

  private static final ThreadFactory FACTORY = new ThreadFactory() {
    private final AtomicInteger next = new AtomicInteger();

    @Override public Thread newThread(Runnable r) {
      final String name = "spectator-gauge-polling-" + next.getAndIncrement();
      final Thread t = new Thread(r, name);
      t.setDaemon(true);
      return t;
    }
  };

  private static final ScheduledExecutorService DEFAULT_EXECUTOR =
      Executors.newSingleThreadScheduledExecutor(FACTORY);

  /** Schedule collection of gauges for a registry. */
  static  void schedule(WeakReference ref, long delay, Consumer poll) {
    schedule(DEFAULT_EXECUTOR, ref, delay, poll);
  }

  /** Schedule collection of gauges for a registry. */
  @SuppressWarnings("PMD")
  static  void schedule(
      ScheduledExecutorService executor, WeakReference ref, long delay, Consumer poll) {
    final AtomicReference> futureRef = new AtomicReference<>();
    final Runnable cancel = () -> {
      Future f = futureRef.get();
      if (f != null) {
        f.cancel(false);
      }
    };
    final Runnable task = () -> {
      try {
        T r = ref.get();
        if (r != null) {
          poll.accept(r);
        } else {
          cancel.run();
        }
      } catch (Throwable t) {
        cancel.run();
      }
    };
    futureRef.set(executor.scheduleWithFixedDelay(task, delay, delay, TimeUnit.MILLISECONDS));
  }

  private GaugePoller() {
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy