51 lines
975 B
Go
51 lines
975 B
Go
package rpc
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
func writeRPCJournal(path string, value any) error {
|
|
directory := filepath.Dir(path)
|
|
if err := os.MkdirAll(directory, 0700); err != nil {
|
|
return err
|
|
}
|
|
file, err := os.CreateTemp(directory, ".rpc-journal-*")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
name := file.Name()
|
|
defer os.Remove(name)
|
|
if err := file.Chmod(0600); err != nil {
|
|
_ = file.Close()
|
|
return err
|
|
}
|
|
if err := json.NewEncoder(file).Encode(value); err != nil {
|
|
_ = file.Close()
|
|
return err
|
|
}
|
|
if err := file.Sync(); err != nil {
|
|
_ = file.Close()
|
|
return err
|
|
}
|
|
if err := file.Close(); err != nil {
|
|
return err
|
|
}
|
|
if err := os.Rename(name, path); err != nil {
|
|
return err
|
|
}
|
|
dir, err := os.Open(directory)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
syncErr := dir.Sync()
|
|
closeErr := dir.Close()
|
|
if err := errors.Join(syncErr, closeErr); err != nil {
|
|
return fmt.Errorf("sync journal directory: %w", err)
|
|
}
|
|
return nil
|
|
}
|