Skip to content

✨ feat(server): implement graceful exit handling with log flushing - #449

Merged
twisti-dev merged 1 commit into
version/26.3from
feat/minestom-exit-and-compat
Oct 17, 2026
Merged

twisti-dev merged 1 commit into
version/26.3from
feat/minestom-exit-and-compat

Conversation

@twisti-dev

Copy link
Copy Markdown
Member
  • add exitFlushingLogs function to stop server and flush logs before JVM termination
  • update SurfMinestomServer to use exitFlushingLogs for graceful shutdown
  • introduce MiniPlaceholdersCommandMixin for compatibility with MiniPlaceholders 3.2.0
  • update gradle.properties to version 3.50.0 and add new dependencies

- add exitFlushingLogs function to stop server and flush logs before JVM termination
- update SurfMinestomServer to use exitFlushingLogs for graceful shutdown
- introduce MiniPlaceholdersCommandMixin for compatibility with MiniPlaceholders 3.2.0
- update gradle.properties to version 3.50.0 and add new dependencies
@twisti-dev twisti-dev self-assigned this Oct 17, 2026
Copilot AI balanced review requested due to automatic review settings October 17, 2026 16:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-17T17:01:17.291682Z 523ab97 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@twisti-dev
twisti-dev merged commit 299e874 into version/26.3 Oct 17, 2026
7 checks passed
@twisti-dev
twisti-dev deleted the feat/minestom-exit-and-compat branch October 17, 2026 16:58

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 523ab970e6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


private fun terminate(): Nothing {
// Waits for a start in progress, so that the server it starts is stopped as well
current.get()?.lifecycleLock?.withLock {}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Stop the runtime that was awaited during startup

When exitFlushingLogs is requested from another thread while start() is in progress, this empty lock acquisition can finish immediately after the startup thread releases lifecycleLock but before it installs the shutdown hook and assigns lastStarted. The exit thread then observes no runtime to stop and calls System.exit, so feature/plugin teardown and registered shutdown actions are skipped, potentially losing data they were expected to flush. Retain and stop the current runtime after waiting, or publish the runtime and hook before releasing the lifecycle lock.

Useful? React with 👍 / 👎.

Comment on lines +190 to +193
override fun exit(status: Int) {
Thread({
try {
exitFlushingLogs(status)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reserve the exit status before launching the worker

When two callers request different exit statuses close together, invocation order is not preserved because this method only starts a thread and exitRequest.compareAndSet runs later inside that thread. A later direct exitFlushingLogs(0) or a more promptly scheduled exit(0) can therefore win over an earlier exit(1), causing a failed server to report a successful process status despite the API promise that the first request wins. Record the request synchronously before starting the asynchronous termination work.

Useful? React with 👍 / 👎.

Comment on lines +239 to +244
Runtime.getRuntime().addShutdownHook(Thread({
try {
stop()
} finally {
LogFlush.flush()
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Flush logs only from the active runtime's shutdown hook

After shutdown() followed by another supported surfMinestomServer() start, both runtimes retain shutdown hooks. On a signal those hooks run concurrently; if the active hook wins Minestom's one-shot stop, the older hook can return from stopCleanly() immediately and reach this flush while the active runtime is still disabling features or running shutdown actions. Shutting Log4j down at that point drops the remaining shutdown logs, so use a single global hook targeting the latest runtime or otherwise coordinate one final flush after all runtime hooks finish.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants