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 {
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
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 {
user = 'xbib'
user = 'jprante'
name = 'metrics'
description = 'A stripped-down and modified version of Coda Hale Metrics'
scmUrl = 'https://github.com/' + user + '/' + name

View file

@ -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"
}

Binary file not shown.

View file

@ -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
View file

@ -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" "$@"

View file

@ -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.
*/

View file

@ -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

View file

@ -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);
}
/**