fix scheduled executor services thread leak, update to Gradle 4.6-rc-1

This commit is contained in:
Jörg Prante 2018-03-02 00:17:59 +01:00
parent 1db95358c5
commit 00150abbb3
10 changed files with 77 additions and 48 deletions

View file

@ -1,13 +1,9 @@
plugins { plugins {
id "org.sonarqube" version "2.2" id "org.sonarqube" version "2.6.1"
id "org.ajoberstar.github-pages" version "1.6.0-rc.1" id "io.codearte.nexus-staging" version "0.11.0"
id "org.xbib.gradle.plugin.jbake" version "1.1.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" + 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", "Build: group: ${project.group} name: ${project.name} version: ${project.version}\n",
InetAddress.getLocalHost(), 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: 'java'
apply plugin: 'maven' apply plugin: 'maven'
apply plugin: 'signing' apply plugin: 'signing'
apply plugin: 'findbugs'
apply plugin: 'pmd'
apply plugin: 'checkstyle'
apply plugin: "jacoco"
apply from: 'gradle/ext.gradle' apply from: 'gradle/ext.gradle'
@ -37,9 +29,9 @@ configurations {
dependencies { dependencies {
testCompile "junit:junit:4.12" testCompile "junit:junit:4.12"
testCompile "org.apache.logging.log4j:log4j-core:2.7" testCompile "org.apache.logging.log4j:log4j-core:2.10.0"
testCompile "org.apache.logging.log4j:log4j-slf4j-impl:2.7" testCompile "org.apache.logging.log4j:log4j-slf4j-impl:2.10.0"
wagon 'org.apache.maven.wagon:wagon-ssh-external:2.10' wagon 'org.apache.maven.wagon:wagon-ssh:3.0.0'
} }
sourceCompatibility = 1.8 sourceCompatibility = 1.8
@ -72,4 +64,3 @@ if (project.hasProperty('signing.keyId')) {
} }
apply from: 'gradle/publish.gradle' apply from: 'gradle/publish.gradle'
apply from: 'gradle/sonarqube.gradle'

6
gradle.properties Normal file
View file

@ -0,0 +1,6 @@
group = org.xbib
name = metrics
version = 1.1.0
junit.version = 4.12
wagon.version = 3.0.0

View file

@ -1,5 +1,5 @@
ext { ext {
user = 'xbib' user = 'jprante'
name = 'metrics' name = 'metrics'
description = 'A stripped-down and modified version of Coda Hale Metrics' description = 'A stripped-down and modified version of Coda Hale Metrics'
scmUrl = 'https://github.com/' + user + '/' + name scmUrl = 'https://github.com/' + user + '/' + name

View file

@ -1,12 +1,13 @@
task xbibUpload(type: Upload) { task xbibUpload(type: Upload) {
group = 'publish'
configuration = configurations.archives configuration = configurations.archives
uploadDescriptor = true uploadDescriptor = true
repositories { repositories {
if (project.hasProperty("xbibUsername")) { if (project.hasProperty("xbibUsername")) {
mavenDeployer { mavenDeployer {
configuration = configurations.wagon configuration = configurations.wagon
repository(url: 'scpexe://xbib.org/repository') { repository(url: project.property('xbibUrl')) {
authentication(userName: xbibUsername, privateKey: xbibPrivateKey) authentication(userName: xbibUsername, privateKey: xbibPrivateKey)
} }
} }
@ -15,6 +16,7 @@ task xbibUpload(type: Upload) {
} }
task sonaTypeUpload(type: Upload) { task sonaTypeUpload(type: Upload) {
group = 'publish'
configuration = configurations.archives configuration = configurations.archives
uploadDescriptor = true uploadDescriptor = true
repositories { repositories {
@ -64,3 +66,7 @@ task sonaTypeUpload(type: Upload) {
} }
} }
} }
nexusStaging {
packageGroup = "org.xbib"
}

Binary file not shown.

View file

@ -1,6 +1,5 @@
#Tue Nov 01 15:47:24 CET 2016
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-rc-1-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.1-bin.zip

19
gradlew vendored
View file

@ -1,4 +1,4 @@
#!/usr/bin/env bash #!/usr/bin/env sh
############################################################################## ##############################################################################
## ##
@ -154,16 +154,19 @@ if $cygwin ; then
esac esac
fi fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules # Escape application args
function splitJvmOpts() { save () {
JVM_OPTS=("$@") for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
} }
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS APP_ARGS=$(save "$@")
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
# 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 # 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")" cd "$(dirname "$0")"
fi fi
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" exec "$JAVACMD" "$@"

View file

@ -1,6 +1,6 @@
package org.xbib.metrics; package org.xbib.metrics;
import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
@ -15,37 +15,51 @@ import java.util.concurrent.atomic.LongAdder;
public class Meter implements Metered { public class Meter implements Metered {
private static final long TICK_INTERVAL = TimeUnit.SECONDS.toNanos(5); private static final long TICK_INTERVAL = TimeUnit.SECONDS.toNanos(5);
private final ExpWeightedMovingAverage m1Rate = ExpWeightedMovingAverage.oneMinuteEWMA(); private final ScheduledExecutorService executorService;
private final ExpWeightedMovingAverage m5Rate = ExpWeightedMovingAverage.fiveMinuteEWMA();
private final ExpWeightedMovingAverage m15Rate = ExpWeightedMovingAverage.fifteenMinuteEWMA(); 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 AtomicLong lastTick;
private final Clock clock; private final Clock clock;
private long startedAt; private long startedAt;
private ScheduledFuture<?> future; private ScheduledFuture<?> future;
/** /**
* Creates a new {@link Meter}. * Creates a new {@link Meter}.
* @param executorService the executor service
*/ */
public Meter() { public Meter(ScheduledExecutorService executorService) {
this(Clock.defaultClock()); this(executorService, Clock.defaultClock());
} }
/** /**
* Creates a new {@link Meter}. * Creates a new {@link Meter}.
* *
* @param executorService the executor service
* @param clock the clock to use for the meter ticks * @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.clock = clock;
this.startedAt = this.clock.getTick();
this.lastTick = new AtomicLong(startedAt); this.lastTick = new AtomicLong(startedAt);
m1Rate = ExpWeightedMovingAverage.oneMinuteEWMA();
m5Rate = ExpWeightedMovingAverage.fiveMinuteEWMA();
m15Rate = ExpWeightedMovingAverage.fifteenMinuteEWMA();
count = new LongAdder();
} }
public void spawn(long intervalSeconds) { public void start(long intervalSeconds) {
this.future = Executors.newScheduledThreadPool(1) this.startedAt = this.clock.getTick();
this.future = executorService
.scheduleAtFixedRate(this::tickIfNecessary, intervalSeconds, intervalSeconds, TimeUnit.SECONDS); .scheduleAtFixedRate(this::tickIfNecessary, intervalSeconds, intervalSeconds, TimeUnit.SECONDS);
} }
@ -53,6 +67,11 @@ public class Meter implements Metered {
future.cancel(false); future.cancel(false);
} }
public void shutdown() {
stop();
executorService.shutdownNow();
}
/** /**
* Mark the occurrence of an event. * Mark the occurrence of an event.
*/ */

View file

@ -10,6 +10,7 @@ import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executors;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -486,7 +487,7 @@ public class MetricRegistry implements MetricSet {
MetricBuilder<Meter> METERS = new MetricBuilder<Meter>() { MetricBuilder<Meter> METERS = new MetricBuilder<Meter>() {
@Override @Override
public Meter newMetric() { public Meter newMetric() {
return new Meter(); return new Meter(Executors.newSingleThreadScheduledExecutor());
} }
@Override @Override
@ -498,7 +499,7 @@ public class MetricRegistry implements MetricSet {
MetricBuilder<Sampler> TIMERS = new MetricBuilder<Sampler>() { MetricBuilder<Sampler> TIMERS = new MetricBuilder<Sampler>() {
@Override @Override
public Sampler newMetric() { public Sampler newMetric() {
return new Sampler(); return new Sampler(Executors.newSingleThreadScheduledExecutor());
} }
@Override @Override

View file

@ -2,6 +2,7 @@ package org.xbib.metrics;
import java.io.Closeable; import java.io.Closeable;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; 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 * Creates a new {@link Sampler} using an {@link ExponentiallyDecayingReservoir} and the default
* {@link Clock}. * {@link Clock}.
* @param executorService the executor service
*/ */
public Sampler() { public Sampler(ScheduledExecutorService executorService) {
this(new ExponentiallyDecayingReservoir()); this(new ExponentiallyDecayingReservoir(), executorService);
} }
/** /**
* Creates a new {@link Sampler} that uses the given {@link Reservoir}. * Creates a new {@link Sampler} that uses the given {@link Reservoir}.
* *
* @param reservoir the {@link Reservoir} implementation the sampler should use * @param reservoir the {@link Reservoir} implementation the sampler should use
* @param executorService the executor service
*/ */
public Sampler(Reservoir reservoir) { public Sampler(Reservoir reservoir, ScheduledExecutorService executorService) {
this(reservoir, Clock.defaultClock()); 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 reservoir the {@link Reservoir} implementation the sampler should use
* @param clock the {@link Clock} 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) { public Sampler(Reservoir reservoir, Clock clock, ScheduledExecutorService executorService) {
this.meter = new Meter(clock);
this.clock = clock;
this.histogram = new Histogram(reservoir); this.histogram = new Histogram(reservoir);
this.clock = clock;
this.meter = new Meter(executorService, clock);
} }
/** /**