Skip to content

Commit bf74ab5

Browse files
committed
Mitigate excessive resource usage from Night Config
1 parent e1ff647 commit bf74ab5

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package org.embeddedt.modernfix.forge.config;
2+
3+
import com.electronwill.nightconfig.core.file.FileWatcher;
4+
import com.google.common.collect.ForwardingCollection;
5+
import com.google.common.collect.ForwardingMap;
6+
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
7+
8+
import java.util.Collection;
9+
import java.util.Iterator;
10+
import java.util.Map;
11+
import java.util.concurrent.TimeUnit;
12+
import java.util.concurrent.locks.LockSupport;
13+
14+
/**
15+
* Throttle NightConfig's file watching. There are reports of this consuming excessive CPU time
16+
* (<a href="https://github.com/TheElectronWill/night-config/pull/144">example</a>) and the spammed iterator calls
17+
* end up being 10% of allocations when testing in a dev environment.
18+
*/
19+
public class NightConfigWatchThrottler {
20+
private static final long DELAY = TimeUnit.MILLISECONDS.toNanos(1000);
21+
22+
@SuppressWarnings("rawtypes")
23+
public static void throttle() {
24+
Map watchedDirs = ObfuscationReflectionHelper.getPrivateValue(FileWatcher.class, FileWatcher.defaultInstance(), "watchedDirs");
25+
ObfuscationReflectionHelper.setPrivateValue(FileWatcher.class, FileWatcher.defaultInstance(), new ForwardingMap() {
26+
@Override
27+
protected Map delegate() {
28+
return watchedDirs;
29+
}
30+
31+
private Collection cachedValues;
32+
33+
@Override
34+
public Collection values() {
35+
if(cachedValues == null) {
36+
Collection values = super.values();
37+
cachedValues = new ForwardingCollection() {
38+
@Override
39+
protected Collection delegate() {
40+
return values;
41+
}
42+
43+
@Override
44+
public Iterator iterator() {
45+
// iterator() is called at the beginning of each iteration of the watch loop,
46+
// so it is a good spot to inject the delay.
47+
LockSupport.parkNanos(DELAY);
48+
return super.iterator();
49+
}
50+
};
51+
}
52+
return cachedValues;
53+
}
54+
}, "watchedDirs");
55+
}
56+
}

forge/src/main/java/org/embeddedt/modernfix/platform/forge/ModernFixPlatformHooksImpl.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.embeddedt.modernfix.forge.classloading.FastAccessTransformerList;
3232
import org.embeddedt.modernfix.forge.classloading.ModernFixResourceFinder;
3333
import org.embeddedt.modernfix.forge.config.NightConfigFixer;
34+
import org.embeddedt.modernfix.forge.config.NightConfigWatchThrottler;
3435
import org.embeddedt.modernfix.forge.init.ModernFixForge;
3536
import org.embeddedt.modernfix.forge.packet.PacketHandler;
3637
import org.embeddedt.modernfix.forge.spark.SparkLaunchProfiler;
@@ -192,6 +193,7 @@ public void injectPlatformSpecificHacks() {
192193
}
193194

194195
NightConfigFixer.monitorFileWatcher();
196+
NightConfigWatchThrottler.throttle();
195197
MixinExtrasBootstrap.init();
196198
}
197199

0 commit comments

Comments
 (0)