Files
alkstore/tasks/mem-engine-locks.md
T

108 lines
5.1 KiB
Markdown

---
id: mem-engine-locks
name: Mem engine — named locks (in-memory TTL registry)
status: completed
depends_on: [mem-engine-seam-tx]
scope: narrow
risk: low
impact: component
level: implementation
tags: [wave-6, mem-engine, locks]
---
## Description
The named-locks mechanism over an in-memory TTL registry
(engine-mem.md §Mapping the contract, locks row):
- `store.try_lock(name, owner, ttl)` — acquire or fail (`Option<Lock>
`; no-work is a value); validation at entry (empty → `InvalidName`,
reserved → `ReservedName`); **duration guard at entry** —
`ttl <= 0` rejects with opaque `Err`
([ADR-023](../architecture/decisions/023-fourth-review-round.md) §2,
durations kind), never a silent immediately-expired lease.
- **`Lock` handle** ([ADR-019](../architecture/decisions/019-mechanism-handle-surfaces.md)):
`renew(ttl)` (absolute reset; renews past expiry refused) and
`release`. Registry entries carry owner + deadline; expiry is a
clock check at try/renew boundaries (tokio time; no ambient
revoker) — after TTL expiry exclusion lapses *silently* (the
ADR-008 §7 row), re-acquirable; the holder may still release.
- **Single-instance contention semantics**: two `try_lock`s on the
same name within the registry are serialized by the guarded-state
discipline — first wins, second gets `None` cleanly (the SQLite
busy-path question has no mem analog; loser is a value, never an
error). Not part of the tx seam (no `lock_tx` — contract-verbatim:
a lock held across a business tx is held by explicit acquisition;
the overlay neither sees nor stages locks).
## Acceptance Criteria
- [x] `try_lock`/`renew`/`release` over the TTL registry; entry
validation (names + duration guard) — pinned
- [x] TTL expiry: silent lapse, re-acquisition, renew-past-expiry
refused — pinned (clock-controlled tests via the state core's
clock accessor)
- [x] Concurrent-contention shape: loser is `None`, winner's lease
intact — pinned
- [x] `cargo check --target wasm32-unknown-unknown -p alkstore-mem`
clean; workspace gates green
## References
- docs/architecture/core-contract.md §named locks
- docs/architecture/decisions/008-contract-v1-pinning.md §7;
019-mechanism-handle-surfaces.md; 023 §2
- docs/architecture/engine-mem.md §Mapping the contract (locks row)
- tasks/pg-engine-locks.md (the structural twin's task of record —
the duration guards land identically)
## Notes
> Filled by implementation agent, 2026-10-10.
1. **The implementation already landed in the seam task** —
`mem-engine-seam-tx` Note 1 (the all-or-nothing trait-impl
disposition, the same one the notify-listen and queues twins
recorded): the `MemLock` registry mechanism in
`alkstore-mem/src/lock.rs` was implemented with the seam's
whole-engine scope; this task found its mechanism *implemented*.
2. **Full coverage reconciliation — zero new tests needed**: every
shape the description and the three acceptance criteria enumerate
was already pinned by the seam suite in `lock.rs`: the contention
shape (first wins, loser `None` as a clean value, same-owner
re-grant without a second lease row — `contention_grants_once_and_
the_loser_reads_none`), the duration guard (`ttl <= 0` → opaque
`Database` `Err` on both `try_lock` and `renew`, ADR-023 §2's
durations kind — `duration_guards_reject_non_positive_ttls`), the
TTL expiry row via the frozen clock (in-TTL refusal, silent lapse,
re-acquisition, old-holder renew refused — `expiry_lapses_silently_
and_reacquires`), renew-past-expiry refused + the new holder's
clean life (`renew_past_expiry_is_refused`), the release shapes
(held-true, past-expiry-still-the-holder's, re-acquired-elsewhere
no-op — `release_shapes`), entry validation (empty/blank/reserved
name, empty owner — `entry_validation`), and the
locks-are-not-tx-scoped posture (the overlay neither sees nor
stages locks — `locks_are_not_tx_scoped`). Note also the seam
task's recorded semantis delta (seam Notes 7): mem pins
renew-past-expiry *refused*, where the SQLite substrate would
revive a not-yet-purged lapsed row — the stricter, contract-honest
arm.
3. **No production code changed and no test changed** — the task is a
disposition: the surface was verified correct as-found.
## Summary
> Filled on completion, 2026-10-10.
Completed the mem engine's locks task as a pure reconciliation: the
TTL-registry mechanism landed with the seam task's whole-engine scope,
and the reconciliation against the description's pin list found all
three acceptance criteria's shapes already unit-pinned in
`alkstore-mem/src/lock.rs`'s seven tests (contention/loser-None,
duration guards on both entry kinds, clock-controlled silent lapse +
re-acquisition + renew-past-expiry refused, release shapes, entry
validation, no-`lock_tx`). No code and no tests changed; acceptance
criteria satisfied as-found. Verified: `cargo test -p alkstore-mem`
green, workspace `cargo test` green, `cargo clippy --all-targets --
-D warnings` clean, `cargo fmt --check` clean,
`cargo check --target wasm32-unknown-unknown -p alkstore-mem` clean.