2

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?

Drakinite
  • 363
  • 1
  • 13
  • I think I figured out something.... Maybe. It's really strange. If I highlight any text, the command window changes to "Select C:\WINDOWS\system32\cmd.exe" and it stops all logging. That's neat that I figured out why the messages all seemed to be buffered.. But it doesn't explain why the script execution paused. – Drakinite Jul 20 '19 at 02:22
  • 1
    https://stackoverflow.com/a/30517482/1541563 – Patrick Roberts Jul 20 '19 at 03:17

0 Answers0