Skip to content

cortexkit-lease: shared-mode leases (acquire_shared)#1

Merged
ualtinok merged 2 commits into
masterfrom
synapse/lease-shared-mode
Jul 8, 2026
Merged

cortexkit-lease: shared-mode leases (acquire_shared)#1
ualtinok merged 2 commits into
masterfrom
synapse/lease-shared-mode

Conversation

@ualtinok

@ualtinok ualtinok commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

What

Adds LeaseStore::acquire_shared: shared holders coexist with each other and block the exclusive writer (and vice versa). File impl via fs2's try_lock_shared — flock(LOCK_SH) on unix, LockFileEx without LOCKFILE_EXCLUSIVE_LOCK on Windows.

Why

First consumer: Synapse's cross-module model cache (~/.local/share/cortexkit/models/). Readers take a shared lease on a blob digest while validating/mmap-ing; GC takes exclusive + two-phase tombstones, so it can never delete a file under a live reader while concurrent readers never serialize each other. (Design: synapse docs/design-synapse-module.md, model-cache section; requested shape per SUBC review pm_31c3ffbf — lease-crate-only, option (a).)

Semantics pinned by tests

  • shared + shared coexist; shared blocks exclusive until the last shared holder drops; exclusive blocks shared
  • shared handles do not bump the fence epoch (not writers) — proven epoch-neutral; they report the last persisted writer epoch for observability
  • cross-process check (unix): a python-fcntl child holds LOCK_SH while the parent's exclusive acquire is Held and a second shared coexists — pins real OS semantics, not per-fd artifacts. On Windows the same-process tests exercise LockFileEx contention directly (its locks are per-handle).

Notes

try_lock_shared is called fully-qualified through the fs2 trait: std 1.89+ ships an inherent File::try_lock_shared returning TryLockError which otherwise shadows the fs2 method (build error caught in this PR's development.

No changes outside the lease crate. cortexkit-store untouched and green.
EOF
)


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Summary by cubic

Add shared-mode leases to cortexkit-lease via LeaseStore::acquire_shared, letting multiple readers coexist while blocking an exclusive writer (and vice versa). Prevents model cache GC from deleting files under live readers without forcing readers to serialize.

  • New Features
    • acquire_shared: shared+shared coexist; exclusive blocks shared; exclusive waits until the last shared drops.
    • Epochs: shared handles don’t bump the write fence; LeaseHandle::epoch() reports the last persisted writer epoch.
    • File backend: uses fs2 try_lock_shared (flock LOCK_SH on Unix, shared LockFileEx on Windows); called fully qualified to avoid std File::try_lock_shared shadowing.
    • Tests: coexistence/blocking, epoch neutrality, and a Unix cross-process check; Windows semantics covered via per-handle locks.

Written for commit dda5aee. Summary will update on new commits.

Review in cubic

ualtinok added 2 commits July 8, 2026 14:04
Shared holders coexist with each other and block the exclusive writer
(and vice versa) — reader-side protection for shared resources like the
cross-module model cache: a reader takes a shared lease on a blob digest
while validating/mmap-ing so GC (exclusive) can never delete under it.

Shared handles do not bump the fence epoch (they are not writers); they
report the last persisted writer epoch for observability.

Semantics proven in tests: shared+shared coexist, shared blocks
exclusive until the LAST shared holder drops, exclusive blocks shared,
epoch neutrality, and a cross-process shared-vs-exclusive check (unix:
python-fcntl child; Windows LockFileEx semantics are exercised by the
same-process tests since its locks are per-handle). try_lock_shared is
called via the fs2 trait fully-qualified: std 1.89+ added an inherent
File::try_lock_shared that would shadow it.
@ualtinok ualtinok merged commit 16aed47 into master Jul 8, 2026
7 checks passed
@ualtinok ualtinok deleted the synapse/lease-shared-mode branch July 8, 2026 12:12
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