HarperFast / HarperFast/harper
Atomic increment racing TTL expiry is non-deterministic and diverges between RocksDB and LMDB
- Dominant language
- JavaScript
- Stars
- 89
- Forks
- 10
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 200
Description
## Summary
An atomic increment (`addTo`) applied to a record at the moment its TTL expires produces a **non-deterministic** result, and the two storage engines disagree.
## Repro
Found via exploratory QA (qa-explorer skill), harper `001bf7b9c` (v5.1.0, main).
Setup: a record with a short TTL and a numeric field; fire an atomic `addTo` increment timed to land right around the TTL-expiry instant.
**Observed:**
- **RocksDB:** flips run-to-run between resurrecting the pre-expiry value (e.g. old value 100 + 10 bids → 110) and starting fresh from 0 (→ 10), with identical code and timing.
- **LMDB:** consistently resurrects the pre-expiry value (110).
- The two engines disagree on the same workload.
**Expected:** deterministic, engine-consistent behavior — either the increment consistently operates on a fresh (post-expiry) record or it's consistently rejected/resurrected, the same way on both engines.
## Not affected
Plain concurrency is fine: 50 parallel atomic increments to a non-expiring record yield exactly 50 with zero lost updates on both engines. The issue is specifically the **increment ⨯ TTL-expiry race**.
## Notes
Not a crash or hang — a correctness/consistency surprise. A scratch reproduction test exists (qa-scratch/auction); run the TTL-race case several times to see the RocksDB flip. Can be promoted to `integrationTests/database/` (gating the race case until fixed).
_Filed from qa-explorer wave 1 (F-002). Medium confidence._
Contributor guide
Assessment
This issue has not been assessed yet.