When introducing async work, retries, or batching:
1) Use each concurrency primitive for its intended role
2) Make concurrency-limit meanings unambiguous
-1), document it where the option is read and ensure callers won’t assume 0 means unlimited.3) Prefer mutex helpers over ad-hoc lock code
concurrency.with_worker_mutex) to avoid race bugs and to centralize lock/timeout/exptime behavior.4) Be careful with timers under locks
0 to avoid timer stack/callsite issues.5) Avoid timer fan-out in batch code
Example pattern (mutex helper + safe reschedule):
local function retrying_sync(premature, retry_count)
if premature then return end
local res, err = concurrency.with_worker_mutex({
name = "get_delta",
timeout = 0,
exptime = 5,
}, function()
return do_sync() -- shared logic; retry decision handled outside if needed
end)
if not res and err ~= "timeout" then
ngx_log(ngx_ERR, "sync failed: ", err)
return
end
-- avoid tail-recursion/timerng crash cases
kong.timer:at(0.1, retrying_sync, (retry_count or 0) + 1)
end
Apply this standard during review by checking: (a) are primitives used for their intended semantics, (b) are unlimited/concurrency-limit semantics consistent, (c) are mutex/timer interactions safe under contention, and (d) does batch logic avoid uncontrolled timer spawning.
Enter the URL of a public GitHub repository