From 1108808ab1c414a9ec67824205a5916689fd2405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Papp?= Date: Thu, 4 Jun 2026 18:31:37 +0200 Subject: [PATCH] [client] Persist sync response only after network map is applied Previously the SyncResponse was persisted to syncStore before updateNetworkMap() ran. If applying the network map failed, the engine persisted state it never applied, so GetLatestSyncResponse() could return stale/unapplied state. Move the persistence into the post-apply success path so the persisted response always reflects what the engine applied. --- client/internal/engine.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/client/internal/engine.go b/client/internal/engine.go index 3515e2e60..bec781627 100644 --- a/client/internal/engine.go +++ b/client/internal/engine.go @@ -953,7 +953,14 @@ func (e *Engine) handleSync(update *mgmProto.SyncResponse) error { return nil } - // Persist sync response under the dedicated lock (syncRespMux), not under syncMsgMux. + // only apply new changes and ignore old ones + if err := e.updateNetworkMap(nm); err != nil { + return err + } + + // Persist sync response only after updateNetworkMap accepted and applied the update, + // so GetLatestSyncResponse() never returns state the engine did not actually apply. + // Done under the dedicated lock (syncRespMux), not under syncMsgMux. // A non-nil syncStore is what marks persistence as enabled. Hold the lock for // the whole Set so the store cannot be cleared (disabled / engine close) // mid-call and have this write resurrect a file that was just removed. @@ -967,11 +974,6 @@ func (e *Engine) handleSync(update *mgmProto.SyncResponse) error { } e.syncRespMux.RUnlock() - // only apply new changes and ignore old ones - if err := e.updateNetworkMap(nm); err != nil { - return err - } - e.statusRecorder.PublishEvent(cProto.SystemEvent_INFO, cProto.SystemEvent_SYSTEM, "Network map updated", "", nil) return nil