I have an old desktop repurposed as a NAS and Minecraft server. I connect to it through Windows Remote Desktop Connection.
I have a script running my Minecraft server java process through Node's built-in child_process.spawn
.
Pieces of my code are as follows:
//Require Node.js standard library function to spawn a child process
var spawn = require('child_process').spawn;
//Create a child process for the Minecraft server using the same java process
minecraftServerProcess = spawn('java', [
'-server',
'-Xmx2048M',
'-Xms2048M',
'-XX:+UseConcMarkSweepGC',
'-XX:+UseParNewGC',
'-XX:+CMSIncrementalPacing',
'-XX:ParallelGCThreads=2',
'-XX:+AggressiveOpts',
'-jar',
'server.jar',
'nogui'
]);
//When process's stdout receives data, send it to log function
minecraftServerProcess.stdout.on('data', log);
minecraftServerProcess.stderr.on('data', log);
//When it is closed DURING REBOOT PROCESS ONLY (isRebooting), boot back up.
minecraftServerProcess.on('close', function(){
if(isRebooting){
//Reset isRebooting
isRebooting = false;
//Boot server
bootServer();
}
}
// Listen for events coming from the minecraft server process - in this case,
// just log out messages coming from the server
function log(data) {
process.stdout.write(data.toString());
//if process is ready, then go to prepare-for-reboot
if(data.includes("Done")){
ready = true;
//Create new Date, "tomorrow at 5:00 AM."
var currentDate = new Date();
var rebootDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate() + 1, 05)
var timeDelta = rebootDate.valueOf() - currentDate.valueOf();
//Log
writeToMinecraftServer(`say Successfully booted server at ${currentDate}.`);
writeToMinecraftServer(`say Preparing to reboot at ${rebootDate}, in ${timeDelta} ms.`);
//****THIS is the line that gives me the most trouble*****
setTimeout(prepareForReboot, timeDelta);
}
}
function writeToMinecraftServer(command){
minecraftServerProcess.stdin.write(command+'\n');
}
function prepareForReboot(){
//Contains a 5-minute countdown timer, but this is what it executes after 5 minutes from a setTimeout callback:
reboot();
}
function reboot(){
//Set isRebooting to true
isRebooting = true;
//Tell server to save and exit.
writeToMinecraftServer("stop");
}
When I boot the server, it creates a timeout to send the "stop" command to the Java process, which allows it to safely exit. The problem is, though, the server doesn't reboot. Here is an example of what I see:
1 day after I booted up the server and closed RDC (remote desktop connection), I come back and see (in my command window; this time PowerShell) that the reboot process did not begin; AND no logs from the Java process have shown up. I press a single key in the command window, then a few dozen messages from the Java process show up (Buffered?); immediately followed by:
[17:42:11] [Server thread/INFO]: [Server] Rebooting in 5 minutes.
The timestamp of that message was at the exact time I pressed a key (5:42 PM), meaning that the function prepareForReboot was not run until I interacted with the command window by pressing a key. I originally thought that it was child_process.spawn.stdin.write
that was the culprit; but if that was the case, then I would see my entire countdown in the buffered logs:
[17:42:11] [Server thread/INFO]: [Server] Rebooting in 5 minutes.
[17:42:11] [Server thread/INFO]: [Server] Rebooting in 1 minute.
[17:42:11] [Server thread/INFO]: [Server] Rebooting in 30 seconds.
[17:42:11] [Server thread/INFO]: [Server] Rebooting in 15 seconds.
[17:42:11] [Server thread/INFO]: [Server] Rebooting in 5 seconds.
[17:42:11] [Server thread/INFO]: [Server] Rebooting...
Summary: I have a Node process running in a command window, on a remote server in my house. The process creates a child_process.spawn object, which runs a Java Minecraft server. Once it boots, it sets a timeout for the following morning at 5:00 AM. BUT the Timeout function does NOT execute when it is scheduled to (note: When Remote Desktop Connection is NOT connected). The Timeout function only BEGINS to be executed AFTER I connect to RDC, and press a key on the command window.
Why is the Node process not executing my Timeout function until I interact with the window? Is there a way to fix that?