fix(gtasks): prevent concurrent push/pull from racing on the store

Problem: `push` and `pull` both run via `oauth.async`, so issuing them
back-to-back starts two coroutines that interleave at every curl yield.
Both snapshot `build_id_index` before either has mutated the store,
which can cause push to create a remote task that pull would have
recognized as already linked, producing duplicates on Google.

Solution: guard `with_token` with a module-level `_in_flight` flag set
before `oauth.async` is called so no second operation can start during
a token-refresh yield. A `pcall` around the callback guarantees the
flag is always cleared, even on an unexpected error.
This commit is contained in:
Barrett Ruth 2026-03-06 15:53:43 -05:00
parent 480c832306
commit 36a5025198

View file

@ -436,15 +436,27 @@ local function sync_setup(access_token)
return tasklists, s, now_ts
end
local _in_flight = false
---@param callback fun(access_token: string): nil
local function with_token(callback)
if _in_flight then
log.warn('gtasks: operation in progress — please wait')
return
end
_in_flight = true
oauth.async(function()
local token = oauth.google_client:get_access_token()
if not token then
_in_flight = false
log.warn('not authenticated — run :Pending auth')
return
end
callback(token)
local ok, err = pcall(callback, token)
_in_flight = false
if not ok then
log.error('gtasks: ' .. tostring(err))
end
end)
end