Skip to content

Commit db32332

Browse files
authored
Merge pull request #285 from Floweynt/async-nonblock
Do not pin threads when handling sync metrics
2 parents 6ad7626 + c4a0588 commit db32332

File tree

2 files changed

+23
-28
lines changed

2 files changed

+23
-28
lines changed

src/main/java/de/sldk/mc/MetricRegistry.java

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import java.util.ArrayList;
66
import java.util.List;
7+
import java.util.Objects;
78
import java.util.concurrent.CompletableFuture;
89

910
public class MetricRegistry {
@@ -28,6 +29,7 @@ CompletableFuture<Void> collectMetrics() {
2829
/* Combine all Completable futures into a single one */
2930
return CompletableFuture.allOf(this.metrics.stream()
3031
.map(Metric::collect)
32+
.filter(Objects::nonNull)
3133
.toArray(CompletableFuture[]::new));
3234
}
3335

src/main/java/de/sldk/mc/metrics/Metric.java

+21-28
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22

33
import io.prometheus.client.Collector;
44
import io.prometheus.client.CollectorRegistry;
5-
import org.bukkit.Bukkit;
6-
import org.bukkit.plugin.Plugin;
7-
85
import java.util.concurrent.CompletableFuture;
9-
import java.util.concurrent.ExecutionException;
106
import java.util.logging.Logger;
7+
import org.bukkit.Bukkit;
8+
import org.bukkit.plugin.Plugin;
9+
import org.jetbrains.annotations.Nullable;
1110

1211
public abstract class Metric {
1312

@@ -27,42 +26,36 @@ protected Plugin getPlugin() {
2726
return plugin;
2827
}
2928

29+
@Nullable
3030
public CompletableFuture<Void> collect() {
31-
return CompletableFuture.runAsync(() -> {
32-
if (!enabled) {
33-
return;
34-
}
35-
36-
/* If metric is capable of async execution run it on a thread pool */
37-
if (isAsyncCapable()) {
31+
if (!isEnabled()) {
32+
return null;
33+
}
3834

35+
if (isAsyncCapable()) {
36+
CompletableFuture.runAsync(() -> {
3937
try {
4038
doCollect();
41-
}
42-
catch (Exception e) {
39+
} catch (Exception e) {
4340
logException(e);
4441
}
45-
return;
46-
}
42+
});
43+
}
4744

48-
/*
49-
* Otherwise run the metric on the main thread and make the
50-
* thread on thread pool wait for completion
51-
*/
45+
CompletableFuture<Void> future = new CompletableFuture<>();
46+
47+
// don't call .get() - this blocks the ForkJoinPool.commonPool and may deadlock the server in some cases
48+
Bukkit.getScheduler().callSyncMethod(plugin, () -> {
5249
try {
53-
Bukkit.getScheduler().callSyncMethod(plugin, () -> {
54-
try {
55-
doCollect();
56-
}
57-
catch (Exception e) {
58-
logException(e);
59-
}
60-
return null;
61-
}).get();
50+
doCollect();
6251
} catch (Exception e) {
6352
logException(e);
6453
}
54+
future.complete(null);
55+
return null;
6556
});
57+
58+
return future;
6659
}
6760

6861
protected abstract void doCollect();

0 commit comments

Comments
 (0)