fix scheduled executor services thread leak, update to Gradle 4.6-rc-1
This commit is contained in:
parent
1db95358c5
commit
00150abbb3
10 changed files with 77 additions and 48 deletions
19
build.gradle
19
build.gradle
|
@ -1,13 +1,9 @@
|
|||
|
||||
plugins {
|
||||
id "org.sonarqube" version "2.2"
|
||||
id "org.ajoberstar.github-pages" version "1.6.0-rc.1"
|
||||
id "org.xbib.gradle.plugin.jbake" version "1.1.0"
|
||||
id "org.sonarqube" version "2.6.1"
|
||||
id "io.codearte.nexus-staging" version "0.11.0"
|
||||
}
|
||||
|
||||
group = 'org.xbib'
|
||||
version = '1.0.0'
|
||||
|
||||
printf "Host: %s\nOS: %s %s %s\nJVM: %s %s %s %s\nGroovy: %s\nGradle: %s\n" +
|
||||
"Build: group: ${project.group} name: ${project.name} version: ${project.version}\n",
|
||||
InetAddress.getLocalHost(),
|
||||
|
@ -24,10 +20,6 @@ printf "Host: %s\nOS: %s %s %s\nJVM: %s %s %s %s\nGroovy: %s\nGradle: %s\n" +
|
|||
apply plugin: 'java'
|
||||
apply plugin: 'maven'
|
||||
apply plugin: 'signing'
|
||||
apply plugin: 'findbugs'
|
||||
apply plugin: 'pmd'
|
||||
apply plugin: 'checkstyle'
|
||||
apply plugin: "jacoco"
|
||||
|
||||
apply from: 'gradle/ext.gradle'
|
||||
|
||||
|
@ -37,9 +29,9 @@ configurations {
|
|||
|
||||
dependencies {
|
||||
testCompile "junit:junit:4.12"
|
||||
testCompile "org.apache.logging.log4j:log4j-core:2.7"
|
||||
testCompile "org.apache.logging.log4j:log4j-slf4j-impl:2.7"
|
||||
wagon 'org.apache.maven.wagon:wagon-ssh-external:2.10'
|
||||
testCompile "org.apache.logging.log4j:log4j-core:2.10.0"
|
||||
testCompile "org.apache.logging.log4j:log4j-slf4j-impl:2.10.0"
|
||||
wagon 'org.apache.maven.wagon:wagon-ssh:3.0.0'
|
||||
}
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
|
@ -72,4 +64,3 @@ if (project.hasProperty('signing.keyId')) {
|
|||
}
|
||||
|
||||
apply from: 'gradle/publish.gradle'
|
||||
apply from: 'gradle/sonarqube.gradle'
|
||||
|
|
6
gradle.properties
Normal file
6
gradle.properties
Normal file
|
@ -0,0 +1,6 @@
|
|||
group = org.xbib
|
||||
name = metrics
|
||||
version = 1.1.0
|
||||
|
||||
junit.version = 4.12
|
||||
wagon.version = 3.0.0
|
|
@ -1,5 +1,5 @@
|
|||
ext {
|
||||
user = 'xbib'
|
||||
user = 'jprante'
|
||||
name = 'metrics'
|
||||
description = 'A stripped-down and modified version of Coda Hale Metrics'
|
||||
scmUrl = 'https://github.com/' + user + '/' + name
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
|
||||
task xbibUpload(type: Upload) {
|
||||
group = 'publish'
|
||||
configuration = configurations.archives
|
||||
uploadDescriptor = true
|
||||
repositories {
|
||||
if (project.hasProperty("xbibUsername")) {
|
||||
mavenDeployer {
|
||||
configuration = configurations.wagon
|
||||
repository(url: 'scpexe://xbib.org/repository') {
|
||||
repository(url: project.property('xbibUrl')) {
|
||||
authentication(userName: xbibUsername, privateKey: xbibPrivateKey)
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +16,7 @@ task xbibUpload(type: Upload) {
|
|||
}
|
||||
|
||||
task sonaTypeUpload(type: Upload) {
|
||||
group = 'publish'
|
||||
configuration = configurations.archives
|
||||
uploadDescriptor = true
|
||||
repositories {
|
||||
|
@ -64,3 +66,7 @@ task sonaTypeUpload(type: Upload) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
nexusStaging {
|
||||
packageGroup = "org.xbib"
|
||||
}
|
||||
|
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,5 @@
|
|||
#Tue Nov 01 15:47:24 CET 2016
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-rc-1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-3.1-bin.zip
|
||||
|
|
23
gradlew
vendored
23
gradlew
vendored
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
|
@ -33,11 +33,11 @@ DEFAULT_JVM_OPTS=""
|
|||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
|
@ -154,16 +154,19 @@ if $cygwin ; then
|
|||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [[ "$(uname)" == "Darwin" ]] && [[ "$HOME" == "$PWD" ]]; then
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
exec "$JAVACMD" "$@"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package org.xbib.metrics;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
@ -15,37 +15,51 @@ import java.util.concurrent.atomic.LongAdder;
|
|||
public class Meter implements Metered {
|
||||
private static final long TICK_INTERVAL = TimeUnit.SECONDS.toNanos(5);
|
||||
|
||||
private final ExpWeightedMovingAverage m1Rate = ExpWeightedMovingAverage.oneMinuteEWMA();
|
||||
private final ExpWeightedMovingAverage m5Rate = ExpWeightedMovingAverage.fiveMinuteEWMA();
|
||||
private final ExpWeightedMovingAverage m15Rate = ExpWeightedMovingAverage.fifteenMinuteEWMA();
|
||||
private final ScheduledExecutorService executorService;
|
||||
|
||||
private final ExpWeightedMovingAverage m1Rate;
|
||||
|
||||
private final ExpWeightedMovingAverage m5Rate;
|
||||
|
||||
private final ExpWeightedMovingAverage m15Rate;
|
||||
|
||||
private final LongAdder count;
|
||||
|
||||
private final LongAdder count = new LongAdder();
|
||||
private final AtomicLong lastTick;
|
||||
|
||||
private final Clock clock;
|
||||
|
||||
private long startedAt;
|
||||
|
||||
private ScheduledFuture<?> future;
|
||||
|
||||
/**
|
||||
* Creates a new {@link Meter}.
|
||||
* @param executorService the executor service
|
||||
*/
|
||||
public Meter() {
|
||||
this(Clock.defaultClock());
|
||||
public Meter(ScheduledExecutorService executorService) {
|
||||
this(executorService, Clock.defaultClock());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Meter}.
|
||||
*
|
||||
* @param executorService the executor service
|
||||
* @param clock the clock to use for the meter ticks
|
||||
*/
|
||||
public Meter(Clock clock) {
|
||||
public Meter(ScheduledExecutorService executorService, Clock clock) {
|
||||
this.executorService = executorService;
|
||||
this.clock = clock;
|
||||
this.startedAt = this.clock.getTick();
|
||||
this.lastTick = new AtomicLong(startedAt);
|
||||
m1Rate = ExpWeightedMovingAverage.oneMinuteEWMA();
|
||||
m5Rate = ExpWeightedMovingAverage.fiveMinuteEWMA();
|
||||
m15Rate = ExpWeightedMovingAverage.fifteenMinuteEWMA();
|
||||
count = new LongAdder();
|
||||
}
|
||||
|
||||
public void spawn(long intervalSeconds) {
|
||||
this.future = Executors.newScheduledThreadPool(1)
|
||||
public void start(long intervalSeconds) {
|
||||
this.startedAt = this.clock.getTick();
|
||||
this.future = executorService
|
||||
.scheduleAtFixedRate(this::tickIfNecessary, intervalSeconds, intervalSeconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
|
@ -53,6 +67,11 @@ public class Meter implements Metered {
|
|||
future.cancel(false);
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
stop();
|
||||
executorService.shutdownNow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the occurrence of an event.
|
||||
*/
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.TreeSet;
|
|||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
@ -486,7 +487,7 @@ public class MetricRegistry implements MetricSet {
|
|||
MetricBuilder<Meter> METERS = new MetricBuilder<Meter>() {
|
||||
@Override
|
||||
public Meter newMetric() {
|
||||
return new Meter();
|
||||
return new Meter(Executors.newSingleThreadScheduledExecutor());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -498,7 +499,7 @@ public class MetricRegistry implements MetricSet {
|
|||
MetricBuilder<Sampler> TIMERS = new MetricBuilder<Sampler>() {
|
||||
@Override
|
||||
public Sampler newMetric() {
|
||||
return new Sampler();
|
||||
return new Sampler(Executors.newSingleThreadScheduledExecutor());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.xbib.metrics;
|
|||
|
||||
import java.io.Closeable;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
|
@ -17,18 +18,20 @@ public class Sampler implements Metered, Sampling {
|
|||
/**
|
||||
* Creates a new {@link Sampler} using an {@link ExponentiallyDecayingReservoir} and the default
|
||||
* {@link Clock}.
|
||||
* @param executorService the executor service
|
||||
*/
|
||||
public Sampler() {
|
||||
this(new ExponentiallyDecayingReservoir());
|
||||
public Sampler(ScheduledExecutorService executorService) {
|
||||
this(new ExponentiallyDecayingReservoir(), executorService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Sampler} that uses the given {@link Reservoir}.
|
||||
*
|
||||
* @param reservoir the {@link Reservoir} implementation the sampler should use
|
||||
* @param executorService the executor service
|
||||
*/
|
||||
public Sampler(Reservoir reservoir) {
|
||||
this(reservoir, Clock.defaultClock());
|
||||
public Sampler(Reservoir reservoir, ScheduledExecutorService executorService) {
|
||||
this(reservoir, Clock.defaultClock(), executorService);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -36,11 +39,12 @@ public class Sampler implements Metered, Sampling {
|
|||
*
|
||||
* @param reservoir the {@link Reservoir} implementation the sampler should use
|
||||
* @param clock the {@link Clock} implementation the sampler should use
|
||||
* @param executorService the executor service
|
||||
*/
|
||||
public Sampler(Reservoir reservoir, Clock clock) {
|
||||
this.meter = new Meter(clock);
|
||||
this.clock = clock;
|
||||
public Sampler(Reservoir reservoir, Clock clock, ScheduledExecutorService executorService) {
|
||||
this.histogram = new Histogram(reservoir);
|
||||
this.clock = clock;
|
||||
this.meter = new Meter(executorService, clock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue