io.split.client.metrics.FireAndForgetMetrics Maven / Gradle / Ivy
package io.split.client.metrics;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import io.split.engine.metrics.Metrics;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* Created by adilaijaz on 9/4/15.
*/
public class FireAndForgetMetrics implements Metrics {
private static final Logger _log = LoggerFactory.getLogger(FireAndForgetMetrics.class);
private final ExecutorService _executorService;
private final Metrics _delegate;
public static FireAndForgetMetrics instance(Metrics delegate, int numberOfThreads, int queueSize) {
ThreadFactoryBuilder threadFactoryBuilder = new ThreadFactoryBuilder();
threadFactoryBuilder.setDaemon(true);
threadFactoryBuilder.setNameFormat("split-fireAndForgetMetrics-%d");
threadFactoryBuilder.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
_log.error("Error in thread: " + t.getName(), e);
}
});
final ExecutorService executorService = new ThreadPoolExecutor(numberOfThreads,
numberOfThreads,
0L,
TimeUnit.MILLISECONDS,
new ArrayBlockingQueue(queueSize),
threadFactoryBuilder.build(),
new ThreadPoolExecutor.DiscardPolicy());
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
executorService.shutdown();
try {
if (!executorService.awaitTermination(10L, TimeUnit.SECONDS)) { //optional *
_log.info("Executor did not terminate in the specified time.");
List droppedTasks = executorService.shutdownNow(); //optional **
_log.info("Executor was abruptly shut down. These tasks will not be executed: " + droppedTasks);
}
} catch (InterruptedException e) {
// reset the interrupt.
Thread.currentThread().interrupt();
}
}
});
return new FireAndForgetMetrics(delegate, executorService);
}
private FireAndForgetMetrics(Metrics delegate, ExecutorService executorService) {
_delegate = delegate;
_executorService = executorService;
}
@Override
public void count(String counter, long delta) {
try {
_executorService.submit(new CountRunnable(_delegate, counter, delta));
} catch (Throwable t) {
// ignore
}
}
@Override
public void time(String operation, long timeInMs) {
try {
_executorService.submit(new TimeRunnable(_delegate, operation, timeInMs));
} catch (Throwable t) {
// ignore
}
}
@Override
public void gauge(String gauge, double value) {
try {
_executorService.submit(new GaugeRunnable(_delegate, gauge, value));
} catch (Throwable t) {
// ignore
}
}
private static final class CountRunnable implements Runnable {
private final Metrics _delegate;
private final String _name;
private final long _delta;
public CountRunnable(Metrics delegate, String name, long delta) {
_delegate = delegate;
_name = name;
_delta = delta;
}
@Override
public void run() {
_delegate.count(_name, _delta);
}
}
private static final class GaugeRunnable implements Runnable {
private final Metrics _delegate;
private final String _name;
private final double _value;
public GaugeRunnable(Metrics delegate, String name, double value) {
_delegate = delegate;
_name = name;
_value = value;
}
@Override
public void run() {
_delegate.gauge(_name, _value);
}
}
private static final class TimeRunnable implements Runnable {
private final Metrics _delegate;
private final String _name;
private final long _timeInMs;
public TimeRunnable(Metrics delegate, String name, long timeInMs) {
_delegate = delegate;
_name = name;
_timeInMs = timeInMs;
}
@Override
public void run() {
_delegate.time(_name, _timeInMs);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy