CloudNet
CloudNet copied to clipboard
Fix: Minestom does not properly shut down
Motivation
Minestom is a very lightweight framework for implementing specialized Minecraft servers.
Especially when the full implementation or behavior of vanilla Minecraft is not needed, Minestom offers a way to run services with very little resources.
One issue that arised in conjunction with CloudNet is that services implemented using Minestom would not properly stop. Minestom would shut down and the service would get unregistered from CloudNet but the processes would be kept running.
Modification
This pull request first exposes and then properly uses the built-in methods for closing resources that prevent the Wrapper process from exiting.
Mainly, this is facilitated by shutting down components that hold thread pools which in turn hold non-daemon threads that specifically prevent the JVM from shutting down.
Result
Services using the Minestom framework now properly shut down and allow CloudNet to advance to the next lifecycle steps.
The changes from this PR can also be used to improve the quality of other implementations.
Other context
Fixes #1304
If you want to test these changes, I have developed a simple minimal Minestom implementation:
package com.github.gianttree.miniminestom
import net.minestom.server.MinecraftServer
import net.minestom.server.timer.TaskSchedule
import java.util.logging.ConsoleHandler
import java.util.logging.Level
import java.util.logging.Logger
fun main() {
val logger = Logger.getLogger("MiniMinestom")
logger.level = Level.ALL
logger.useParentHandlers = false
logger.addHandler(ConsoleHandler().apply {
level = Level.ALL
})
logger.info("Starting MiniMinestom...")
val hostAddress = System.getProperty("service.bind.host")
logger.fine("Host address: $hostAddress")
if (hostAddress == null) {
logger.severe("Host address not set!")
return
}
val hostPort = Integer.getInteger("service.bind.port")
logger.fine("Host port: $hostPort")
if (hostPort == null) {
logger.severe("Host port not set!")
return
}
val server = MinecraftServer.init()
logger.fine("Server initialized")
val scheduler = MinecraftServer.getSchedulerManager()
scheduler.scheduleTask(
{
logger.info("Stopping server")
MinecraftServer.stopCleanly()
},
TaskSchedule.seconds(2),
TaskSchedule.stop()
)
logger.info("Starting server")
server.start(hostAddress, hostPort)
logger.info("Server started")
}
Closed in favor of #1338