waveterm/pkg/util
Copilot 4956c92c55
Make Wave home config writes atomic and serialized to avoid watcher partial reads (#2945)
`WriteWaveHomeConfigFile()` previously used direct `os.WriteFile`, which
can expose truncation/partial-write states to the JSON file watcher.
This change switches config persistence to temp-file + rename semantics
and serializes writes through a single process-wide lock for config file
writes.

- **Atomic file write helper**
  - Added `AtomicWriteFile()` in `pkg/util/fileutil/fileutil.go`.
- Writes to `<filename>.tmp` in the same directory, then renames to the
target path.
  - Performs temp-file cleanup on error paths.
- Introduced a shared suffix constant (`TempFileSuffix`) used by
implementation/tests.

- **Config write path update**
- Updated `WriteWaveHomeConfigFile()` in `pkg/wconfig/settingsconfig.go`
to:
- Use a package-level mutex (`configWriteLock`) so only one config write
runs at a time (across all config files).
- Call `fileutil.AtomicWriteFile(...)` instead of direct
`os.WriteFile(...)`.

- **Focused coverage for atomic behavior**
  - Added `pkg/util/fileutil/fileutil_test.go` with tests for:
- Successful atomic write (target file contains expected payload and no
leftover `.tmp` file).
    - Rename-failure path cleanup (temp file is removed).

```go
func WriteWaveHomeConfigFile(fileName string, m waveobj.MetaMapType) error {
    configWriteLock.Lock()
    defer configWriteLock.Unlock()

    fullFileName := filepath.Join(wavebase.GetWaveConfigDir(), fileName)
    barr, err := jsonMarshalConfigInOrder(m)
    if err != nil {
        return err
    }
    return fileutil.AtomicWriteFile(fullFileName, barr, 0644)
}
```

<!-- START COPILOT CODING AGENT TIPS -->
---

🔒 GitHub Advanced Security automatically protects Copilot coding agent
pull requests. You can protect all pull requests by enabling Advanced
Security for your repositories. [Learn more about Advanced
Security.](https://gh.io/cca-advanced-security)

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sawka <2722291+sawka@users.noreply.github.com>
2026-02-27 15:43:37 -08:00
..
daystr Happy new year! (#1684) 2025-01-04 20:56:57 -08:00
dbutil new tevents analytics framework (#1894) 2025-02-03 15:32:44 -08:00
ds Fix bugs with connection switching (#2957) 2026-02-27 15:23:55 -08:00
envutil Persistent Terminal Sessions (+ improvements and bug fixes) (#2806) 2026-01-28 13:30:48 -08:00
fileutil Make Wave home config writes atomic and serialized to avoid watcher partial reads (#2945) 2026-02-27 15:43:37 -08:00
iochan Add S3 fileshare implementation, improve cp behavior (#1896) 2025-02-14 17:27:02 -08:00
iterfn wsh file overhaul without cross-remote copy and S3 (#1790) 2025-01-22 14:50:09 -08:00
logutil reduce some logging for prod release (#2440) 2025-10-15 22:10:00 -07:00
logview Happy new year! (#1684) 2025-01-04 20:56:57 -08:00
migrateutil Happy new year! (#1684) 2025-01-04 20:56:57 -08:00
packetparser very large refactor of wshrouter (#2732) 2026-01-01 17:44:00 -08:00
pamparse Simplify regex and fix tests for pamparse (#1712) 2025-01-10 13:53:24 -08:00
readutil New AIPanel (#2370) 2025-10-07 13:32:10 -07:00
shellutil detect if omz is installed and shell completion mode in zsh (#2891) 2026-02-19 10:22:56 -08:00
sigutil very large refactor of wshrouter (#2732) 2026-01-01 17:44:00 -08:00
syncbuf Happy new year! (#1684) 2025-01-04 20:56:57 -08:00
unixutil fix windows compilation error (#2862) 2026-02-11 14:57:27 -08:00
utilfn New ConnMonitor to Track "Stalled" Connection State for SSH Conns (#2846) 2026-02-09 17:11:55 -08:00