Skip to content

Close the lease-client gaps the port reviews found - #126

Merged
bpapillon merged 13 commits into
mainfrom
bpapillon/sch-7530-lease-client-gaps-found-in-the-port-reviews-that-node-go-and
Sep 20, 2026
Merged

bpapillon merged 13 commits into
mainfrom
bpapillon/sch-7530-lease-client-gaps-found-in-the-port-reviews-that-node-go-and

Conversation

@bpapillon

Copy link
Copy Markdown
Collaborator

Python leg of SCH-7530, matching schematic-node #194 commit for commit.

  • Re-read the lease after winning the extend flight, so a stale row cannot send a second extend.
  • Write the reservation hash and its TTL in one MULTI; the index writes stay outside.
  • Feed a preflight set on the evaluation context to the local engine through the same merge as REST.
  • Bound the drain and the local lease release by one shutdown budget.
  • Round a fractional preflight quantity up at the WASM boundary; the engine rejects floats there.
  • Round the hold and the settle debit up to whole event units, so the local ledger moves by exactly what the track event bills. SPEC.md and the vectors are copied from Node, with the new fractional-usage.json.
  • Resolve company keys through the cache first and only fall back to a comp_-prefixed value as the Schematic id, the order the server uses.
  • A joiner joins an in-flight extend only when that extend covers its shortfall, and after two joins sends exactly one extend of its own.
  • Move the cached company metric only when a settle landed locally.
  • Cap a joiner's wait at the caller's own timeout while the shared extend runs on.

Already correct in Python and pinned by the new vector: no wait on a cache miss while disconnected, and the settle quantity rounding up on the wire.

@bpapillon
bpapillon requested a review from a team as a code owner September 18, 2026 18:02
The expiry index is what the sweeper reaches a surviving byCredit field
through, so removing it first and then failing on the field orphans that
field: nothing points at it any more and reserved_credits reads high for
that tenant forever. Swapping the order leaves the recoverable failure
instead, since a surviving index entry is swept.

Found reviewing the Java port (schematic-java#109), whose store already
does it in this order; schematic-go does too, and schematic-node took
the same change as 923dee5.

Also name the conformance suite's real source: the vectors track
schematic-node's conformance directory, not a particular branch of it.
Having a `pipeline` attribute is not the same as honouring
`transaction=True`. redis-py's asyncio cluster client carries the
attribute and raises RedisClusterException before any I/O, so the
getattr guard let the refusal escape add(). The caller in check.py
catches it, undoes the debit and returns lease_store_error, which
fail-closes every gated check on a cluster deployment. That is a
regression: the two writes used to go out directly and worked there.

Probe by calling it instead, so both a cluster client and a shim that
does not take the keyword resolve to the sequential path.
@bpapillon
bpapillon merged commit 3e2be6c into main Sep 20, 2026
6 checks passed
@bpapillon
bpapillon deleted the bpapillon/sch-7530-lease-client-gaps-found-in-the-port-reviews-that-node-go-and branch September 20, 2026 06:01
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.

2 participants