v0.44.1
What changed
OpenOptions and lock_timeout_ms for Database::open_with_options
New opt-in knob for cross-process lock acquisition. Default 0 keeps the historical fail-fast behavior; pass OpenOptions { lock_timeout_ms: 5_000 } for SQLite-style busy_timeout semantics with 1ms, then 10ms, then 50ms backoff against a hard deadline. Lets multiple writers commit cleanly against the same database instead of the second opener seeing locked by another process.
create* constructors now refuse to clobber an existing database
Database::create, create_encrypted, create_with_key, create_with_credentials, and create_encrypted_with_credentials now return MongrelError::InvalidArgument("database already exists at <path>; use Database::open() to open it, or remove the directory first") when the on-disk CATALOG file is present. Previously these would silently overwrite a populated directory, destroying the catalog and any encryption keys. Use Database::open* to open an existing database.
Lock retry respects error class
The cross-process lock retry loop now only treats WouldBlock as retryable. Other I/O errors (PermissionDenied, NotFound, etc.) bubble up immediately instead of being treated as "locked, try again" and looping or hiding the real problem.
Tests
- New
crates/mongreldb-core/tests/cross_process_lock.rs: 5 tests covering fail-fast, retry-until-acquired, retry-with-no-timeout, retry-after-engine-holder-releases, and a 4-writer subprocess harness that commits 100 rows cleanly with the newlock_timeout_msknob. - New
database_basic.rscases for thereject_existing_databaseguard across plain, encrypted, and encrypted + credentialed paths. - Writer subprocess PK fixed from
idxtowriter_id * rows + idxso parallel writers no longer collide on the primary key.
Misc
OpenOptionsnow derivesDefault(was a hand-rolledimpl Default).fail_fast_default_rejects_concurrent_opentiming slack bumped 500ms to 2s to stop CI flake on slow machines.
Full Changelog: v0.44.0...v0.44.1