From f98a23418fb7986ac3948e0966b15a2857350e43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milo=C5=A1=20Jovanovi=C4=87?= Date: Thu, 24 Sep 2026 20:01:01 -0700 Subject: [PATCH] add delta sync before each reconcile, have it not repeat if it's been done in the last minute --- reconcile.go | 3 +++ server.go | 2 ++ sync.go | 17 +++++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/reconcile.go b/reconcile.go index 34492c1..9eb22fc 100644 --- a/reconcile.go +++ b/reconcile.go @@ -6,6 +6,9 @@ import ( ) func (s *Server) reconcile(ctx context.Context, runID int64, rep *User, dept string) error { + if err := s.syncIfStale(ctx, time.Minute); err != nil { + log.Printf("run %d: pre-run sync failed, using cached roster: %v", runID, err) + } reps, err := s.store.RepsFor(rep.ChapterID, dept) if err != nil { return err diff --git a/server.go b/server.go index cebbb4a..a8ab49f 100644 --- a/server.go +++ b/server.go @@ -9,6 +9,7 @@ import ( "strconv" "strings" "time" + "sync" ) // User is the subset of an ST user record this worker cares about. @@ -53,6 +54,7 @@ type Server struct { eligible map[string]bool // runTimeout caps a single reconcile. runTimeout time.Duration + syncMu sync.Mutex } func NewServer(st STClient, store Store, secret string, eligible map[string]bool) *Server { diff --git a/sync.go b/sync.go index 678ca40..843817f 100644 --- a/sync.go +++ b/sync.go @@ -44,3 +44,20 @@ func (s *Server) SyncRoster(ctx context.Context) error { log.Printf("synced %d users (since=%d)", len(users), since) return s.store.SetLastSync(started) } + +// syncIfStale runs a delta sync unless one completed within maxAge (1 min) +// Serialized so a burst of runs triggers one sync, not one each. +func (s *Server) syncIfStale(ctx context.Context, maxAge time.Duration) error { + s.syncMu.Lock() + defer s.syncMu.Unlock() + + last, err := s.store.LastSync() + if err != nil { + return err + } + if time.Since(time.Unix(last, 0)) < maxAge { + return nil + } + return s.SyncRoster(ctx) +} +