Skip to content

fix(gateway): make the renew and rotation locks atomic within a node - #1357

Merged
kvinwang merged 1 commit into
nextfrom
fix/gateway-cert-lock-atomic
Sep 24, 2026
Merged

kvinwang merged 1 commit into
nextfrom
fix/gateway-cert-lock-atomic

Conversation

@kvinwang

@kvinwang kvinwang commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator

Split from #1235.

Both lease locks (per-domain cert renew lock, global ACME rotation lock) read under a read guard, dropped it, then wrote under a write guard, so two tasks on one node could both acquire. That is reachable: the renew loop races an operator's RenewZtDomainCert, and rotation, CAA reconciliation and first-use registration share the rotation lock. Concurrent renewals delete each other's _acme-challenge TXT records.

  • Both locks now go through one try_acquire_lock / release_lock pair holding a single write guard across read, expiry check and write.
  • Release deletes only the lock it acquired. The rotation lock already did this; the cert lock did not, so a renewal that outlived the timeout deleted its successor's lock. Admin.ForceReleaseCertLock keeps an unconditional delete as force_release_cert_lock.

Across nodes this stays best-effort: WaveKV is last-writer-wins without CAS.

two_tasks_on_one_node_cannot_both_acquire and a_holder_that_was_taken_over_does_not_release_the_new_holder_lock fail against next.

@kvinwang
kvinwang added this pull request to stack #1361 September 24, 2026 08:06
Base automatically changed from fix/gateway-zt-domain-normalize to next September 24, 2026 08:07
@kvinwang
kvinwang force-pushed the fix/gateway-cert-lock-atomic branch from 8a27fa1 to 2aca705 Compare September 24, 2026 08:07
Both lease locks read under a read guard, dropped it, then wrote under a
write guard, so two tasks on one node could both acquire: with eight threads
racing on one KvStore, several acquired the same cert lock. The background
renew loop and an operator's RenewZtDomainCert reach that concurrently, as do
rotation, CAA reconciliation and first-use registration for the rotation lock.

Both locks now go through one try_acquire_lock / release_lock pair that holds a
single write guard across read, expiry check and write. Release only deletes
the lock it acquired, which the rotation lock already did and the cert lock did
not: a renewal that outlived the timeout deleted its successor's lock.
Admin.ForceReleaseCertLock keeps an unconditional delete as
force_release_cert_lock.

Across nodes this stays best-effort: WaveKV is last-writer-wins without
compare-and-swap, so two nodes can both acquire during a replication gap.
@kvinwang
kvinwang force-pushed the fix/gateway-cert-lock-atomic branch from 2aca705 to ee333d8 Compare September 24, 2026 08:16
@kvinwang kvinwang changed the title fix(gateway): make the certificate renew lock atomic locally and owned on release fix(gateway): make the renew and rotation locks atomic within a node Sep 24, 2026
@kvinwang
kvinwang merged commit 9db0b6f into next Sep 24, 2026
14 checks passed
@kvinwang
kvinwang deleted the fix/gateway-cert-lock-atomic branch September 24, 2026 08:46
kvinwang added a commit that referenced this pull request Sep 25, 2026
…t and lock tests

PR #1380 refuses a sync or push envelope that claims the target's own
node id; tc-gw-cluster-ad-002 sends one on both routes. tc-gw-kv-009 now
requires by name the bounded peer client test (#1374) and the atomic
lease-lock tests (#1357).

Signed-off-by: Kevin Wang <wy721@qq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant