Skip to content

NightConfig's FileWatcher not correctly shutdown causing servers to hang #1626

Description

@MrCrayfish

Minecraft Version: 1.21.1
NeoForge Version: 21.1.45

Steps to Reproduce:

  1. Perform a fresh installation of NeoForge server
  2. Launch the server
  3. Go into config directory and change a property in neoforge-common.toml. Very important, this will trigger NightConfig to summon non-daemon thread
  4. Examine debug.log to confirm the log was printed Config file neoforge-common.toml changed, re-loading.
  5. Now run stop command and you should see the server hangs even after all dimension saving, etc

Description of issue:
I've had a report on my own mods that dedicated servers were hanging after running the stop command (MrCrayfish/MrCrayfishFurnitureMod-Refurbished#30). After investigating the issue, it seems that NeoForge is not correctly shutting down FileWatcher from NightConfig. NeoForge (and Forge) both use FileWatcher.defaultInstance() to add/remove paths to watch but never call stop(). This is a problem since NightConfig summons a non-daemon thread, and this won't be terminated unless FileWatcher#stop() is called.

Below is a very rudimentary test I created that replicates the similar behavior of config files in NeoForge. Tested using NightConfig 3.7.3 and 3.8.1. (Here is a link to the setup: https://gist.github.com/MrCrayfish/5e0a285b6226b84a5e04d6949dfdf4f2)

Path file = Files.createTempFile("test-config", ".toml");
FileWatcher.defaultInstance().addWatch(file, () -> { // Add to watch like in ConfigTracker#openConfig
    // Callback ignored
});
Thread.sleep(Duration.ofMillis(1000)); // Wait for FileWatcher to setup
Files.write(file, Arrays.asList("Hello")); // Write to file. This is the same as editing neoforge-common.toml and changing a value.
Thread.sleep(Duration.ofMillis(1000)); // Give time for FileWatcher to detect
FileWatcher.defaultInstance().removeWatch(file); // Remove watch like in ConfigTracker#unload
Thread.sleep(Duration.ofMillis(1000));
// End of application but will not terminate

However reverting to versions of NightConfig before the big overhaul of FileWatcher (TheElectronWill/night-config#148), specifically versions lower than 3.7.0, the issue does not occur. The above test will successfully terminate on version 3.6.4.

Solution, call FileWatcher#stop() on shutdown of server and clients.

Metadata

Metadata

Assignees

No one assigned

    Labels

    1.21.4Targeted at Minecraft 1.21.4bugA bug or errornot usCaused by a dependency or a third party

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions