Repository navigation
Conversation
The GC credited the first sighting of a mount token with a clock sample taken before the LIST of gc/server-roots/ and the slot read. A slow walk then counted as time the token was watched, and a later round could write gc_fenced over a holder whose last renewal still gave it authority. Both callers of computeHeartbeatFloor (the regular round and the rebuild) now pass the observer clock as a function; the sighting is sampled after the read, including the re-decision after a refused fence-out. The stability test keeps its entry sample, and a sample older than the sighting never counts as time held, so the elapsed time cannot wrap. Closes backlog task CAS-342. Related: #2431 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…aiming its slot Every observer waited its own cas_mount_lease_ttl_ms before treating an unchanged slot token as a dead holder: the GC floor, the same-server restart and remount reclaim. A holder configured with a longer lease was fenced inside its own right to write when any observer ran with a shorter value, and nothing in the protocol could tell. Observers now wait max(own lease, declared lease) + 5 % + their own poll step, where the declared lease is expires_at_ms - started_at_ms of the body they observe (0 when the stamps are missing, equal, or reversed, so the wait is never shorter than before). The formula stays in one place, mountObservationThresholdMs, and saturates instead of wrapping. The setting is per server: how long this server may write after its last confirmed renewal; every other server waits at least that long. Mixed values are safe in any order. The GC leader logs one WARNING per slot whose declared lease differs from its own; fenced and departed slots are not warned about. Signed-off-by: Mikhail Filimonov <mfilimonov@altinity.com> Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
11 of 31 tasks
k-morozov
reviewed
Oct 12, 2026
Observers wait for the lease a holder declares, so an hour-long `cas_mount_lease_ttl_ms` would block reclaim of a silently dead member for an hour. Clamp the configured value to 600000 ms when the settings load, with one warning naming the configured and effective values. The renewal deadline, the slot's `expires_at_ms` and the observer's own threshold all read the clamped setting. The observer side does not clamp what a holder declares. Signed-off-by: Mikhail Filimonov <mfilimonov@altinity.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
k-morozov
previously approved these changes
Oct 15, 2026
filimonov
dismissed
k-morozov’s stale review
October 15, 2026 09:48
The merge-base changed after approval.
9 of 31 tasks
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Every observer of a CAS mount slot — the GC floor, the same-server restart and the self-remount reclaim — waited its own
cas_mount_lease_ttl_msbefore treating an unchanged slot token as a dead holder. A holder configured with a longer lease was fenced inside its own right to write as soon as any observer ran with a shorter value, and nothing in the protocol could tell. Observers now wait for the lease the holder declares.Stacked on #2509: the diff shows that commit until it merges.
Why it matters for the lease
The observer never compares clocks across servers; the only thing that makes a fence safe is waiting at least the holder's lease on its own clock. With the renewal rework that follows (#2431) a live holder will routinely keep one token for tens of seconds, so a mismatched lease on one server becomes the most likely path to fencing a live writer. The declared lease is already in the slot body (
expires_at_ms − started_at_ms); using it removes the "one value on every server, change it with the pool stopped" rule.Changes
mountObservationThresholdMs(own, declared, cadence)=max(own, declared) + 5 % + cadence, saturating on overflow (a wrapped sum would fence early; waiting forever is the safe side). The declared lease is 0 when the stamps are missing, equal (farewell) or reversed, so no observer waits less than before.claimMountAwaitingExpiryuses the body it compares the token against. 27 call sites pass the observer's own lease and step instead of a ready-made threshold. The fast paths (gc_fenced, clean farewell) are untouched.cas_mount_lease_ttl_ms, hostname, pid and the declared value; not for fenced or departed slots; no counter, observation or write changes.cas_mount_lease_ttl_msis a per-server setting — how long this server may write after its last confirmed renewal; every other server waits at least that long. Mixed values are safe in any order.Risks / notes
started_at_msandexpires_at_msfrom one wall-clock reading, so the declared lease equals the holder's TTL.Testing
gtest_cas_mount.cpp,gtest_cas_gc_ack_floor.cpp,gtest_cas_pool.cpp): red on the base — GC floor with a holder declaring 60 s against the observer's 30 s: no fence at 41.5 s or 72.999 s, fence at 73 s (round and rebuild); restart reclaim 64 s against 33 s; declaring 10 s, zero stamps or a farewell keeps the own rule; the WARNING once per slot and silent for terminal slots. Expected values are literals; six formula mutations each turn their test red. Behaviour-preservation:gc_fencedand farewell slots are reclaimed without waiting.CAS*gate: 2633 (release), 2637 (ASan, no error);test_cas_mount_renewal_retry: 4 passed.Related: #2431
Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes to CHANGELOG.md):
CAS observers (GC fencing, restart and remount reclaim) wait for the lease a mount holder declares in its slot, so a longer
cas_mount_lease_ttl_mson one server is never fenced early by a server with a shorter one; the setting is per server and mixed values are safe.Documentation entry for user-facing changes
Updated
docs/en/antalya/cas/architecture/mounts-and-leases.md,docs/en/antalya/cas/configuration.md,docs/en/antalya/cas/architecture/garbage-collection.md.CI/CD Options
Exclude tests:
Regression jobs to run: