Skip to content

Make YAML persistence atomic - #298

Closed
BenCodez wants to merge 17 commits into
masterfrom
refactor/file-persistence
Closed

BenCodez wants to merge 17 commits into
masterfrom
refactor/file-persistence

Conversation

@BenCodez

Copy link
Copy Markdown
Owner

Summary

Harden AdvancedCore YAML writes while preserving existing configuration paths and save entry points.

  • add AtomicYamlWriter to serialize into a sibling temporary file before replacing the destination
  • prefer an atomic move when the filesystem supports it, with a replace fallback otherwise
  • keep FilesManager.editFile(...) asynchronous but route its write through the atomic replacement helper
  • override ServerData.saveData() so its existing immediate-save setters retain their behavior without truncating the last good file during a failed serialization
  • replace raw persistence stack traces in these paths with contextual AdvancedCore logging
  • preserve all existing ServerData keys and public methods

Tests

  • verifies replacement YAML fully replaces the previous contents
  • verifies temporary files are cleaned after a successful write
  • verifies missing parent directories are created

This PR changes persistence mechanics only; it does not rename or migrate configuration keys.

@BenCodez
BenCodez marked this pull request as ready for review August 24, 2026 23:12
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@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: dec3058038

ℹ️ 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".

@BenCodez
BenCodez marked this pull request as draft August 25, 2026 00:04
@BenCodez
BenCodez marked this pull request as ready for review August 25, 2026 00:21
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@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: 456d53ebc6

ℹ️ 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".

@BenCodez
BenCodez marked this pull request as draft August 25, 2026 00:27
@BenCodez
BenCodez marked this pull request as ready for review August 25, 2026 00:51
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@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: 75955cf147

ℹ️ 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".

@BenCodez
BenCodez marked this pull request as draft August 25, 2026 01:12
@BenCodez
BenCodez marked this pull request as ready for review August 25, 2026 01:28
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@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: 0d02255705

ℹ️ 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".

@BenCodez
BenCodez marked this pull request as draft August 25, 2026 01:48
@BenCodez
BenCodez marked this pull request as ready for review August 25, 2026 01:56
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@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: 0b8d1f16f5

ℹ️ 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".

@BenCodez
BenCodez marked this pull request as draft August 25, 2026 02:02
@BenCodez
BenCodez marked this pull request as ready for review August 25, 2026 02:14
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@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: 7b77c6d892

ℹ️ 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".

@BenCodez
BenCodez marked this pull request as draft August 25, 2026 02:35
@BenCodez
BenCodez marked this pull request as ready for review August 25, 2026 02:43
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for security reviews. Please try again later.

@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: 1fd4a6229d

ℹ️ 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".

Comment on lines +225 to +226
Files.deleteIfExists(preserved);
Files.createLink(preserved, target);

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 Serialize commits that share a destination

When two threads or server processes save the same resolved YAML concurrently, both transactions use this single fixed preserved-inode path, so one can delete or relink the other transaction's backup while its subsequent copy and move operations are still running. The interleaved operations can then copy into the wrong inode, lose the destination's metadata, throw after partially completing a save, or produce inconsistent contents; use destination-scoped cross-process synchronization or transaction-unique sidecars with ownership validation.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Acknowledged — this is valid and is not fixed on current head 1fd4a6229d0b6559ac4f662ad09413b3e5ac8457. The fixed .advancedcore-preserved-inode sidecar can collide across concurrent writers, so this thread should remain open until the transaction is serialized per resolved destination or uses uniquely owned sidecars. I’m requesting a fresh Codex review of the current head now to catch any additional persistence issues before the next patch.


private static void commitThroughPreservedInode(Path temp, Path target, Path preserved) throws IOException {
Files.deleteIfExists(preserved);
Files.createLink(preserved, target);

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 Fall back when hard links are unavailable

When an existing YAML resides on a POSIX-view filesystem that does not support hard links, such as some network or virtual mounts, every save reaches this call and fails even though creating the sibling temporary file and replacing the destination may be supported. Because createLink has no fallback, both ServerData and reward persistence stop working after the file exists; fall back to metadata-preserving replacement or the compatible in-place path when hard-link creation is unsupported.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Acknowledged — this is valid and is not fixed on current head 1fd4a6229d0b6559ac4f662ad09413b3e5ac8457. Existing POSIX files currently depend on Files.createLink(...); mounts that expose POSIX attributes but reject hard links need a safe fallback rather than failing the save. I’m leaving this thread open and requesting a fresh Codex review of the current head now so any other filesystem compatibility issues are surfaced before the next patch.

Copy link
Copy Markdown
Owner Author

@codex review

@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: 1fd4a6229d

ℹ️ 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".


boolean committed = false;
try {
data.save(temp.toFile());

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 Force the temporary file before exposing it

When the host loses power after moveReplacement(temp, target) but before copyCompleteContents forces the preserved inode, data.save(...) has only closed the temporary file and has not forced its contents to stable storage. The rename can therefore survive while some YAML data blocks do not, leaving the live path empty or partial; on the next save, recoverPreservedInode copies that damaged path over the known-good preserved inode. Force the serialized temporary file before the first move, and durably sync the containing directory where supported.

Useful? React with 👍 / 👎.

if (!targetOwner.equals(tempAcl.getOwner())) {
tempAcl.setOwner(targetOwner);
}
return true;

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 Preserve non-ACL metadata before replacing Windows files

On an ACL-capable non-POSIX filesystem such as NTFS, this successful branch copies only the ACL and owner and then replaces the destination inode. Existing DOS attributes such as hidden/system/archive and user-defined attributes or alternate data streams are consequently discarded after the first save, whereas the previous in-place writer retained them. Preserve the remaining supported attribute views or use the metadata-bearing inode commit path for these destinations.

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.

1 participant