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

com.newrelic.telemetry.LimitingScheduler Maven / Gradle / Ivy

package com.newrelic.telemetry;

import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A scheduler that delegates to a ScheduledExecutorService while also enforcing a maximum upper
 * bound of the amount of work that is being done. For our purposes, the amount of work corresponds
 * to the number of telemetry items "in-flight" (being buffered) in memory.
 *
 * 

A call to schedule() will include a work unit "size" that is accumulated, and if the max would * be exceeded then the work unit is rejected and a warning is logged. */ public class LimitingScheduler { private static final Logger logger = LoggerFactory.getLogger(LimitingScheduler.class); private final ScheduledExecutorService executor; private final int max; private final Semaphore semaphore; public LimitingScheduler(ScheduledExecutorService executor, int max) { this.executor = executor; this.max = max; this.semaphore = new Semaphore(max); } public boolean schedule(int size, Runnable command) { return schedule(size, command, 0, TimeUnit.MILLISECONDS); } public boolean schedule(int size, Runnable command, long delay, TimeUnit unit) { if (!semaphore.tryAcquire(size)) { logger.warn( "Refusing to schedule batch of size " + size + " (would put us over max size " + max + ", available = " + semaphore.availablePermits() + ")"); logger.warn("DATA IS BEING LOST!"); return false; } try { executor.schedule( () -> { try { command.run(); } finally { semaphore.release(size); } }, delay, unit); return true; } catch (RejectedExecutionException e) { logger.warn("Data is being lost, job could not be scheduled", e); semaphore.release(size); return false; } } public boolean isTerminated() { return executor.isTerminated(); } public void shutdown() { executor.shutdown(); } public boolean awaitTermination(int shutdownSeconds, TimeUnit seconds) throws InterruptedException { return executor.awaitTermination(shutdownSeconds, seconds); } public void shutdownNow() { executor.shutdownNow(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy