Run IRC socket I/O on a dedicated background thread
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
Auto-connect on CLIENT_STARTED, .irc reconnect and .irc <msg> all used to open a TCP socket on the render thread with a 5s connect timeout, freezing client startup and chat input when the server was unreachable. Dispatch those paths through a single daemon executor instead, and release the socket plus the executor on CLIENT_STOPPING.
This commit is contained in:
@@ -11,12 +11,21 @@ import net.minecraft.network.chat.Component;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public final class ClientIrcMod implements ClientModInitializer {
|
||||
public static final String MOD_ID = "clientirc";
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
|
||||
|
||||
private static final String COMMAND_PREFIX = ".irc";
|
||||
|
||||
private static final ExecutorService IO_EXECUTOR = Executors.newSingleThreadExecutor(runnable -> {
|
||||
Thread thread = new Thread(runnable, "clientirc-io");
|
||||
thread.setDaemon(true);
|
||||
return thread;
|
||||
});
|
||||
|
||||
private static IrcConfig config;
|
||||
private static IrcService service;
|
||||
|
||||
@@ -27,10 +36,16 @@ public final class ClientIrcMod implements ClientModInitializer {
|
||||
|
||||
ClientLifecycleEvents.CLIENT_STARTED.register(client -> {
|
||||
if (config.autoConnect) {
|
||||
service.connect(resolvePlayerName(client));
|
||||
String playerName = resolvePlayerName(client);
|
||||
IO_EXECUTOR.execute(() -> service.connect(playerName));
|
||||
}
|
||||
});
|
||||
|
||||
ClientLifecycleEvents.CLIENT_STOPPING.register(client -> {
|
||||
service.disconnect();
|
||||
IO_EXECUTOR.shutdownNow();
|
||||
});
|
||||
|
||||
ClientTickEvents.END_CLIENT_TICK.register(client -> {
|
||||
IrcService.DisplayLine line;
|
||||
while ((line = service.pollLine()) != null) {
|
||||
@@ -63,9 +78,12 @@ public final class ClientIrcMod implements ClientModInitializer {
|
||||
}
|
||||
|
||||
if ("reconnect".equalsIgnoreCase(argument)) {
|
||||
boolean connected = service.reconnect(resolvePlayerName(client));
|
||||
ChatFormatting color = connected ? ChatFormatting.GREEN : ChatFormatting.RED;
|
||||
pushClientChat(client, Component.literal("[IRC] reconnect " + (connected ? "ok" : "failed")).withStyle(color));
|
||||
String playerName = resolvePlayerName(client);
|
||||
IO_EXECUTOR.execute(() -> {
|
||||
boolean connected = service.reconnect(playerName);
|
||||
ChatFormatting color = connected ? ChatFormatting.GREEN : ChatFormatting.RED;
|
||||
pushClientChat(client, Component.literal("[IRC] reconnect " + (connected ? "ok" : "failed")).withStyle(color));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -76,15 +94,16 @@ public final class ClientIrcMod implements ClientModInitializer {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!service.ensureConnected(resolvePlayerName(client))) {
|
||||
pushClientChat(client, Component.literal("[IRC] server is offline or config is wrong").withStyle(ChatFormatting.RED));
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean sent = service.sendChat(resolvePlayerName(client), argument);
|
||||
if (!sent) {
|
||||
pushClientChat(client, Component.literal("[IRC] send failed").withStyle(ChatFormatting.RED));
|
||||
}
|
||||
String playerName = resolvePlayerName(client);
|
||||
IO_EXECUTOR.execute(() -> {
|
||||
if (!service.ensureConnected(playerName)) {
|
||||
pushClientChat(client, Component.literal("[IRC] server is offline or config is wrong").withStyle(ChatFormatting.RED));
|
||||
return;
|
||||
}
|
||||
if (!service.sendChat(playerName, argument)) {
|
||||
pushClientChat(client, Component.literal("[IRC] send failed").withStyle(ChatFormatting.RED));
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user