ru.fix.stdlib.concurrency.futures.ProfiledPendingFutureLimiter Maven / Gradle / Ivy
package ru.fix.stdlib.concurrency.futures;
import ru.fix.aggregating.profiler.Identity;
import ru.fix.aggregating.profiler.Profiler;
import ru.fix.dynamic.property.api.DynamicProperty;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
/**
* @author Tim Urmancheev
*/
public class ProfiledPendingFutureLimiter extends PendingFutureLimiter implements AutoCloseable {
private final Profiler profiler;
private final Map tags;
public ProfiledPendingFutureLimiter(DynamicProperty maxPendingCount,
DynamicProperty maxFutureExecuteTimeout,
Profiler namedProfiler) {
this(maxPendingCount, maxFutureExecuteTimeout, namedProfiler, Collections.emptyMap());
}
public ProfiledPendingFutureLimiter(DynamicProperty maxPendingCount,
DynamicProperty maxFutureExecuteTimeout,
Profiler namedProfiler,
Map tags) {
super(maxPendingCount.get(), maxFutureExecuteTimeout.get());
this.profiler = namedProfiler;
this.tags = tags;
maxPendingCount.addListener((oldValue, newValue) -> setMaxPendingCount(newValue));
maxFutureExecuteTimeout.addListener((oldValue, newValue) -> setMaxFutureExecuteTime(newValue));
attachIndicators();
}
@Override
protected CompletableFuture internalEnqueue(CompletableFuture future, boolean needToBlock) throws InterruptedException {
profiler.profileFuture("future_lifetime", () -> future);
return super.internalEnqueue(future, needToBlock);
}
private void attachIndicators() {
profiler.attachIndicator(new Identity(".pending", tags), this::getPendingCount);
profiler.attachIndicator(new Identity(".threshold", tags), () -> (long) this.getThreshold());
profiler.attachIndicator(new Identity(".max_capacity", tags), () -> (long) this.getMaxPendingCount());
}
@Override
public void close() {
profiler.detachIndicator(new Identity(".pending", tags));
profiler.detachIndicator(new Identity(".threshold", tags));
profiler.detachIndicator(new Identity(".max_capacity", tags));
}
}