mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
feat: Add Support for Optimistic Cloud Sync (#273)
* feat: Add support for background sync * refactor: Maintain single source of truth for command defn * fix: Code review fixes * fix: Code review fixes * docs: Add corner case inline doc
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
package audit
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gofrs/flock"
|
||||
)
|
||||
|
||||
// NewSyncLock returns an unlocked file lock at the given path. The same path
|
||||
// must be used by manual `pmg cloud sync` and the auto-sync background child
|
||||
// so they serialize against each other.
|
||||
func NewSyncLock(path string) *flock.Flock {
|
||||
return flock.New(path)
|
||||
}
|
||||
|
||||
// ReadLastSyncAttempt returns the timestamp of the most recent sync attempt
|
||||
// (success or failure). A missing or unparseable file resolves to the zero
|
||||
// time so callers can treat "never attempted" as "infinitely old".
|
||||
func ReadLastSyncAttempt(path string) time.Time {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
secs, err := strconv.ParseInt(strings.TrimSpace(string(data)), 10, 64)
|
||||
if err != nil {
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
return time.Unix(secs, 0)
|
||||
}
|
||||
|
||||
// WriteLastSyncAttempt records the current time as the latest sync attempt.
|
||||
// Both the success and failure code paths must call this so a failing cloud
|
||||
// endpoint does not trigger an attempt on every PMG invocation.
|
||||
func WriteLastSyncAttempt(path string) error {
|
||||
contents := []byte(strconv.FormatInt(time.Now().Unix(), 10))
|
||||
return os.WriteFile(path, contents, 0o600)
|
||||
}
|
||||
|
||||
// SyncCooldownElapsed reports whether enough time has passed since the last
|
||||
// recorded sync attempt to allow a new one.
|
||||
func SyncCooldownElapsed(path string, minInterval time.Duration) bool {
|
||||
last := ReadLastSyncAttempt(path)
|
||||
if last.IsZero() {
|
||||
return true
|
||||
}
|
||||
return time.Since(last) >= minInterval
|
||||
}
|
||||
Reference in New Issue
Block a user