Skip to content

[core] Write changelog files atomically and skip empty changelog files - #10254

Open
LuciferYang wants to merge 2 commits into
apache:masterfrom
LuciferYang:m/core-059-changelog-atomic
Open

LuciferYang wants to merge 2 commits into
apache:masterfrom
LuciferYang:m/core-059-changelog-atomic

Conversation

@LuciferYang

Copy link
Copy Markdown
Contributor

Purpose

ChangelogManager had two related weaknesses around changelog metadata files.

commitChangelog wrote the changelog JSON with fileIO.writeFile(path, json, true), a direct overwrite of the target path. A crash during that write leaves an empty or partial file at the canonical changelog path, while snapshots and hint files are already committed atomically. This changes commitChangelog to fileIO.tryToWriteAtomic, which writes a temp file and renames it into place. When the atomic write returns false because the target already exists, the same id must carry the same content, so the commit is treated as idempotent and only a genuinely different content raises an error.

safelyGetAllChangelogs logged "Changelog file is empty" but then still called Changelog.fromJson on the empty string. That parse throws UncheckedIOException, which the consumer's catch (IOException) does not catch, so it propagates and aborts the whole enumeration. The only caller, OrphanFilesClean, then fails entirely because of one empty or torn file. This skips empty changelog files so the listing stays resilient, matching the intent already expressed by the method name and its existing FileNotFoundException handling.

This closes #10252.

Tests

Added ChangelogManagerTest with two cases. testCommitChangelogWritesAtomically verifies the target path is never opened for a direct overwrite and that repeating a commit of the same id is idempotent while a different content for the same id fails. testSafelyGetAllChangelogsSkipsEmptyFile writes one valid and one empty changelog file and asserts the empty one is skipped.

API and Format

No.

Documentation

No.

The empty-file branch logged a warning but still fell through to
Changelog.fromJson, which throws UncheckedIOException on the empty
string and escaped the IOException-only catch, killing the whole
enumeration — and with it the orphan files clean — over one torn or
truncated changelog file.

Skip the file after the warning, as the branch intended.

Assisted-by: GLM-5.3
commitChangelog wrote the JSON directly to the target file with
overwrite, so a crash midway left readers with an empty or partial
changelog file, which safelyGetAllChangelogs then had to tolerate.
Write through a temp file and rename like snapshot and schema commits,
and treat an already-existing file as an idempotent retry only when its
content matches.

Assisted-by: GLM-5.3
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.

[Bug] Changelog commit is not atomic and an empty changelog file aborts safelyGetAllChangelogs

1 participant