91 lines
5.7 KiB
Markdown
91 lines
5.7 KiB
Markdown
# Persistence and failure recovery
|
||
|
||
The project format is v10. Readers migrate v1–v9, validate bounded input
|
||
and atomically install a candidate only after complete success. Existing tests
|
||
cover exact migration/roundtrip, truncations, malformed references, counts,
|
||
IDs, nonfinite values and failed GUI/backend installation. Native processors
|
||
are session-only; saving their graph returns UNSUPPORTED rather than writing
|
||
process addresses or an unreadable project. See PROJECT_FORMAT.md.
|
||
|
||
Project Save writes a mode-0600 same-directory `NAME.tmp.XXXXXX`, flushes and
|
||
fsyncs it, closes and renames it over the destination. Before rename, handled
|
||
failures remove the temporary and retain the destination. POSIX rename gives
|
||
complete old-or-new destination contents during process failure. The containing directory is fsynced after rename. If that sync fails, Save
|
||
reports I/O failure but the complete new file may already be present. Preserve
|
||
and validate it before retrying; filesystem/hardware durability still varies. Symlinks are
|
||
replaced rather than followed at rename; original file permissions are not kept.
|
||
|
||
Recording similarly writes/finalizes a same-directory temporary, then renames
|
||
it. Stop must synchronize callbacks before draining/finalizing. Ring overflow
|
||
returns an explicit error and may finalize a partial take for manual recovery;
|
||
I/O failure retains the previous destination. A killed recorder does not finish
|
||
its WAV header. Source WAV files remain external; references inside the project folder are
|
||
saved relative to it. Save As does not collect them. Back up the project and assets together.
|
||
|
||
## After a crash
|
||
|
||
1. Preserve the destination and any `.tmp.*` files before attempting repair.
|
||
2. Run `xtc-check --validate project.xtc` for metadata validation without a GUI,
|
||
display or audio server. Run `xtc-check --inspect project.xtc` to list resolved
|
||
media/module paths and plugin identities: status 2 means missing/unreadable
|
||
references, 1 means invalid metadata/I/O, 0 means files are available. Neither
|
||
command verifies file contents, plugin initialization or realtime preparation.
|
||
3. A valid destination can be opened normally. If only a temporary contains useful
|
||
data, copy it to a separate candidate and validate that copy before replacing
|
||
anything. Partial project files are rejected; there is no salvage parser.
|
||
4. An unfinished WAV temporary may have a zero/incorrect data length and needs
|
||
a separate recovery tool or manual header repair on a copy. xtc does not guess
|
||
its intended length or automatically rename orphan temporaries.
|
||
5. Missing assets preserve silent clips. Use Relink selected audio, then Play to
|
||
revalidate. For server loss/format changes, Stop/Reconnect and explicit routing
|
||
are required. Panic/F9 clears held notes. Failed close retains ownership for retry.
|
||
|
||
There is no autosave, crash journal, automatic orphan recovery or persisted Undo
|
||
history. Existing finalized files are protected against the tested process-level
|
||
failures; unsaved edits/in-flight takes can still be lost.
|
||
|
||
`make test-recovery` uses temporary directories and child processes only. It
|
||
forces an EFBIG-style write failure with a child-local file-size limit, kills
|
||
eight project writers while temporaries are visible, and kills a recorder after
|
||
draining but before finalization. Complete old/new destinations and explicit
|
||
orphan temporaries are verified. It does not cut power, terminate the shared
|
||
audio server, simulate a failing filesystem, or qualify disk/device endurance.
|
||
|
||
## Phase 13 retained recording prefixes
|
||
|
||
Recording now defaults to no-clobber publication; the GUI requires an unused
|
||
path. Failed nonempty temporary recordings survive destruction. Query the
|
||
recorder recovery path before destruction, or use the GUI's reported path.
|
||
`xtc-check --recover-recording TEMP NEW.wav` reconstructs a canonical mono
|
||
float32 WAV from complete on-disk frames, ignoring a trailing partial frame.
|
||
It never changes the source or overwrites an existing destination. This
|
||
supersedes the earlier lack of a WAV recovery tool described above. See
|
||
AUDIO_FILES.md for format/ownership/size limits and `make test-recording`.
|
||
|
||
## Plugin load and replacement failures (Phase 25)
|
||
|
||
GUI Open reports an unavailable/incompatible plugin's label and absolute module
|
||
path and retains the current document. Preserve the saved file; restore a
|
||
compatible module at its original path and retry Open. `xtc-check --validate`
|
||
checks metadata without executing plugins, so success does not certify that a
|
||
module exists or initializes. Metadata-only C load/save preserves unavailable
|
||
plugin records. There is no automatic missing-plugin substitution or GUI relink
|
||
for an unopened document.
|
||
|
||
For an already loaded project, Replace selected plugin preserves wires and node
|
||
ID only for the same audio layout. New defaults replace controls/automation;
|
||
Undo restores the original configuration. Failed discovery/compile/instantiate
|
||
retains the original graph, controls and history position. Cancel in the generic
|
||
parameter editor discards its temporary values. Reset defaults clears automation
|
||
only when applied. No host recovery can contain a crash or hang in trusted native
|
||
plugin code; LADSPA has no runtime error-return channel.
|
||
|
||
## Save diagnostics (Phase 28)
|
||
|
||
`make test-project-diagnostics` deterministically injects flush, file-sync, close,
|
||
rename and directory-sync errors. Pre-rename failures retain the previous bytes
|
||
and clean temporary files. Post-rename sync errors leave a complete new file and
|
||
return failure; there is no rollback after replacement. Load diagnostics identify
|
||
the expected record and syntax line, or line zero for whole-model/I/O stages.
|
||
Unknown versions report the supported range (1–10); unknown records/fields are
|
||
rejected without partially changing the current project.
|