atomicfile

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 28, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package atomicfile publishes a whole file so that a concurrent reader observes only the old contents or the new ones, and so that a publication reported as successful is one the data survives a power loss.

Both halves matter and they are different properties. Writing in place is visible half-written: a reader that catches a truncated state file does not see fewer records, it sees a file that fails to parse. Writing to a temporary file in the same directory and renaming it makes the switch a single operation, so there is no moment at which the file is neither version.

Durability is the half that is easy to leave out. A rename that has returned has changed a directory entry the filesystem may not have committed yet, and the temporary file's bytes may not be committed either — so a publication is only complete once the file has been synced before the rename and the directory after it. This package exists because the four call sites that republish local state each hand-rolled the temporary-file dance and none of them did that.

It deliberately does no locking. Atomic publication and isolation between writers are separate concerns: a writer that decided what to write from an earlier read still erases a second writer's record, however atomic the rename. internal/lockfile owns that half, and a caller that republishes state needs both.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ModeOf

func ModeOf(path string, fallback fs.FileMode) fs.FileMode

ModeOf returns path's current permission bits, or fallback when path does not exist or cannot be inspected. It is how a publication preserves the mode of a file another program owns instead of imposing one.

A file this tool did not create is not this tool's to re-permission: forcing a mode onto it would be a side effect of writing one setting. Lstat rather than Stat, so following a link cannot pick up the mode of something else entirely — and anything Lstat reports as not a regular file falls back, because Publish replaces a path with a regular file and the bits of a link or a directory are not a mode a regular file can be published at. A symlink carries 0755 on darwin and 0777 on linux, so reporting its bits would hand a caller a settings file the whole machine can read, or on linux write.

func Publish

func Publish(path string, data []byte, mode fs.FileMode) error

Publish writes data as path, replacing whatever is there, so that a concurrent reader sees either the old file or the complete new one and a successful return means the new contents are durable.

The temporary file is removed on every failure path. A leftover is a complete copy of whatever was being published, sitting next to the real file under a name nothing else would ever clean up — and for this tool that content is local state about real repositories.

func SyncDir

func SyncDir(dir string) error

SyncDir asks the filesystem to make dir's entries durable, so a rename that has returned survives a power loss.

A platform or filesystem with no such request is not a publication failure. Some filesystems refuse a directory fsync outright, and refusing to publish there would break correct installations over a guarantee that platform does not offer in the first place: see unsupportedDirSync.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL