fix: shut down co-processes on dedicated servers even if the server failed to start
This commit is contained in:
parent
ed442168e5
commit
d8e15bdb34
@ -2,31 +2,34 @@ package io.gitlab.jfronny.libjf.coprocess;
|
|||||||
|
|
||||||
import io.gitlab.jfronny.libjf.LibJf;
|
import io.gitlab.jfronny.libjf.LibJf;
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.ModInitializer;
|
|
||||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class CoProcessManager implements ModInitializer {
|
public class CoProcessManager {
|
||||||
private final List<CoProcess> coProcesses = new ArrayList<>();
|
private static final List<CoProcess> coProcesses = new ArrayList<>();
|
||||||
@Override
|
|
||||||
public void onInitialize() {
|
static {
|
||||||
coProcesses.addAll(FabricLoader.getInstance().getEntrypoints(LibJf.MOD_ID + ":coprocess", CoProcess.class));
|
coProcesses.addAll(FabricLoader.getInstance().getEntrypoints(LibJf.MOD_ID + ":coprocess", CoProcess.class));
|
||||||
Runtime.getRuntime().addShutdownHook(new Thread(this::stop));
|
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.SERVER) ServerLifecycleEvents.SERVER_STOPPED.register(server -> CoProcessManager.stop());
|
||||||
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.SERVER) ServerLifecycleEvents.SERVER_STOPPED.register(server -> this.stop());
|
Runtime.getRuntime().addShutdownHook(new Thread(CoProcessManager::stop));
|
||||||
start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void start() {
|
private static final AtomicBoolean started = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
public static void start() {
|
||||||
|
if (started.getAndSet(true)) return;
|
||||||
for (CoProcess coProcess : coProcesses) {
|
for (CoProcess coProcess : coProcesses) {
|
||||||
coProcess.start();
|
coProcess.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stop() {
|
public static void stop() {
|
||||||
|
if (!started.getAndSet(false)) return;
|
||||||
for (Iterator<CoProcess> iter = coProcesses.iterator(); iter.hasNext(); ) {
|
for (Iterator<CoProcess> iter = coProcesses.iterator(); iter.hasNext(); ) {
|
||||||
CoProcess coProcess = iter.next();
|
CoProcess coProcess = iter.next();
|
||||||
coProcess.stop();
|
coProcess.stop();
|
||||||
|
@ -1,13 +1,24 @@
|
|||||||
package io.gitlab.jfronny.libjf.coprocess;
|
package io.gitlab.jfronny.libjf.coprocess;
|
||||||
|
|
||||||
public abstract class ThreadCoProcess implements CoProcess, Runnable {
|
public abstract class ThreadCoProcess implements CoProcess, Runnable {
|
||||||
|
private final boolean isDaemon;
|
||||||
private Thread th = null;
|
private Thread th = null;
|
||||||
private boolean closed = true;
|
private boolean closed = true;
|
||||||
|
|
||||||
|
protected ThreadCoProcess() {
|
||||||
|
this(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ThreadCoProcess(boolean isDaemon) {
|
||||||
|
this.isDaemon = isDaemon;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
if (th != null) stop();
|
if (th != null) stop();
|
||||||
closed = false;
|
closed = false;
|
||||||
th = new Thread(this, getClass().getSimpleName());
|
th = new Thread(this, getClass().getSimpleName());
|
||||||
|
th.setDaemon(isDaemon);
|
||||||
th.start();
|
th.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
package io.gitlab.jfronny.libjf.mixin;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.libjf.coprocess.CoProcessManager;
|
||||||
|
import net.fabricmc.api.DedicatedServerModInitializer;
|
||||||
|
import net.minecraft.server.Main;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.dedicated.MinecraftDedicatedServer;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@Mixin(Main.class)
|
||||||
|
public class MainMixin {
|
||||||
|
@Unique private static boolean libjf$started = false;
|
||||||
|
|
||||||
|
@Inject(method = "main", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/server/MinecraftServer;startServer(Ljava/util/function/Function;)Lnet/minecraft/server/MinecraftServer;"))
|
||||||
|
private static void onStartServer(String[] args, CallbackInfo ci) {
|
||||||
|
libjf$started = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "main", at = @At("RETURN"))
|
||||||
|
private static void onMain(String[] args, CallbackInfo ci) {
|
||||||
|
if (!libjf$started) CoProcessManager.stop();
|
||||||
|
}
|
||||||
|
}
|
@ -18,9 +18,10 @@
|
|||||||
"fabric-lifecycle-events-v1": "*"
|
"fabric-lifecycle-events-v1": "*"
|
||||||
},
|
},
|
||||||
"entrypoints": {
|
"entrypoints": {
|
||||||
"main": ["io.gitlab.jfronny.libjf.coprocess.CoProcessManager"],
|
"main": ["io.gitlab.jfronny.libjf.coprocess.CoProcessManager::start"],
|
||||||
"preLaunch": ["io.gitlab.jfronny.libjf.LibJf"]
|
"preLaunch": ["io.gitlab.jfronny.libjf.LibJf"]
|
||||||
},
|
},
|
||||||
|
"mixins": ["libjf-base.mixins.json"],
|
||||||
"custom": {
|
"custom": {
|
||||||
"modmenu": {
|
"modmenu": {
|
||||||
"parent": "libjf",
|
"parent": "libjf",
|
||||||
|
14
libjf-base/src/main/resources/libjf-base.mixins.json
Normal file
14
libjf-base/src/main/resources/libjf-base.mixins.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"required": true,
|
||||||
|
"minVersion": "0.8",
|
||||||
|
"package": "io.gitlab.jfronny.libjf.mixin",
|
||||||
|
"compatibilityLevel": "JAVA_16",
|
||||||
|
"mixins": [
|
||||||
|
],
|
||||||
|
"server": [
|
||||||
|
"MainMixin"
|
||||||
|
],
|
||||||
|
"injectors": {
|
||||||
|
"defaultRequire": 1
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user