v0.9.9 — Feature complete #7
jamesgober
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Release Notes for v0.9.9 - Native eyes
Version 0.9.9 - 2026-05-12
The watch feature gets its real backend. Through 0.9.8 the implementation was a polling thread that re-stat'd the file at 100 ms intervals, which was reasonable on Linux/macOS but unreliable on Windows where the mtime granularity is too coarse for sub-second changes (three watch tests were
#[cfg_attr(windows, ignore)]'d as a consequence). This release replaces all of that with the OS-native event source on every platform:inotifyon Linux, FSEvents on macOS, andReadDirectoryChangesWon Windows. Backed by thenotify 6crate gated on thewatchfeature, withdefault-featuresoff and only themacos_fseventselector enabled to keep the transitive set tight.Public API is unchanged:
MemoryMappedFile::watch(callback)still returns aResult<WatchHandle>, the callback still receivesChangeEvent { offset, len, kind }with the same 3-variantChangeKind. The breaking aspect is implementation-side timing. Polling delivered changes after a ~100 ms detection window; native backends deliver in <1 ms on Linux, <10 ms on Windows, <50 ms on macOS (FSEvents coalesces by design). Callers who used the previous 100 ms delivery as a de-facto debounce floor will see events sooner. The three previously-ignored Windows watch tests run live on every platform now, plus a newtests/watch_native.rsfile with five integration tests covering modify, truncate, extend, rapid-sequence, and removed.This release also formalizes the 1.0.0 hold: the codebase is structurally ready for 1.0 after 0.9.10 closes (fuzz, examples, performance docs, migration guide), but 1.0.0 is on indefinite hold pending cross-repo presentation work (consistent headers/branding/SECURITY.md across the project family). The previously-planned
1.0.0-rc.1candidate phase is dropped: hyphenated tags caused tooling issues in prior cycles, soak happens on the last 0.9.x in real-world deployment, and 1.0.0 ships directly when it ships. ROADMAP updated accordingly.Highlights
inotifyon Linux delivers events as the kernel sees them (typical <1 ms from file change to callback). FSEvents on macOS batches at ~50 ms granularity by design.ReadDirectoryChangesWon Windows delivers in <10 ms. The platform-behavior table is in the rustdoc onMemoryMappedFile::watchand indocs/API.md.notify 6as the abstraction layer.notify::recommended_watcherpicks the best backend at compile time; we wrap it with ourWatchHandletype that owns the underlying watcher plus a dispatcher thread that drains the event channel and translates eachnotify::EventKindinto our coarserChangeKind. The translation is inmap_notify_kindand is intentionally conservative: anything that's not clearly metadata or removal surfaces asModifiedso callers refresh rather than miss a real change.watch::tests::test_watch_file_changes,watch::tests::test_multiple_watchers, andtests/feature_integration.rs::test_all_features_integrationall lose their#[cfg_attr(windows, ignore = "...")]markers and pass on every platform.tests/watch_native.rs:watch_modify_detected,watch_truncate_detected,watch_extend_detected,watch_rapid_sequence_coalesces_or_reports_each,watch_removed_event_terminates_dispatcher. Each usesstd::fsAPI writes from a separate file handle to simulate the real-world "another process modified the file" scenario.WatchHandle::Droptears down cleanly. Drops the underlyingnotify::RecommendedWatcherfirst (which closes the OS subscription synchronously and the internal channel), then detaches the dispatcher thread via a join wrapper so the dropping thread is never blocked past the OS's own teardown time.WatchHandle::is_active()is now part of the surface (was previously#[allow(dead_code)]); useful for tests and diagnostics.Bug-class changes
std::fs::metadata().modified()returned timestamps quantized to the FS-level resolution, so two writes within the same tick looked identical and the watch loop missed the second.ReadDirectoryChangesWoperates on raw filesystem change notifications and does not depend on mtime, so the granularity issue disappears entirely.loop { sleep; poll }until the file was deleted;WatchHandle::Dropsignaled it via anAtomicBool(audit H5 fix in 0.9.5). The new implementation's thread exits as soon as the channel closes, which happens synchronously when theRecommendedWatcherdrops. NoAtomicBool, no polling interval to wait for.Important note: mmap-write detection
mmap-side writes (
mmap.update_region(...)followed bymmap.flush()) are not a reliable trigger for any platform's native FS watcher. The writes go through the page cache and only reach the watcher at OS-decided writeback time, which is platform-dependent and never well-bounded. This is the same story as on every other native filesystem watcher in existence (notify-rs's docs note this; inotify's man page documents the limitation).For reliable cross-platform detection, modify the file through the
std::fsAPI from another process or another file handle. This matches the actual real-world use case forwatch: detect changes made by something other than the current mapping holder. The rustdoc onMemoryMappedFile::watchcalls this out, the README has a one-line note in the watch example, and the integration tests are written this way (write viastd::fs::OpenOptions+write_all+sync_all).Breaking changes
No public API breaks. The full surface of
MemoryMappedFile::watch,WatchHandle,ChangeEvent, andChangeKindis unchanged.The implementation-side change in event timing (faster delivery) is the only behavioral difference visible to callers. If you were relying on the old ~100 ms polling delay as an implicit debounce floor, add explicit debouncing on top of the callback (wait N ms after the last event before reacting). Most callers will simply observe their
changedflag flip faster.Tests
--all-features(up from 121 in 0.9.8), 1 ignored (the unrelated hugepages-fallback test), 0 failed. The 3 Windows-ignored watch tests are now live, and 5 new integration tests landed intests/watch_native.rs.--no-default-featuresand--no-default-features --features "cow locking advise".cargo fmt --checkclean.cargo clippy --all-targets --all-features -D warningsclean.cargo +1.75 build --all-featuresclean.notify 6.1.xadvertises MSRV 1.60; the transitive set addscrossbeam-channel,mio(Linux),filetime, andwindows-sys-derived shims (Windows).Documentation
docs/API.mdwatch section fully rewritten. Platform-behavior table (Linux <1 ms / macOS <50 ms / Windows <10 ms typical latencies), coalescing notes, error contract, the mmap-write caveat. Install snippets bumped to 0.9.9. Version history entry added.README.mdfeature-table entry rewritten ("Native file-change notifications: inotify (Linux), FSEvents (macOS), ReadDirectoryChangesW (Windows)"). Watch example block updated. mmap-write caveat note added.REPS.mdwatch surface markedSince 0.9.9: backed by notify..dev/ROADMAP.mdrestructured: 1.0.0 placed on indefinite hold with the rationale documented (cross-repo presentation cleanup),1.0.0-rc.1removed entirely (hyphenated tags caused prior tooling issues), versioning strategy through hold documented as "continue with 0.9.x; jump to 0.10.0 if necessary, but prefer 0.9 to 1.0 trajectory."Roadmap status
Notes
mmap-io-watch:<path>so it's easy to identify intop/ Task Manager / debugger views.notifywas chosen over hand-rolled per-platform code because it has been stress-tested by thousands of downstream crates over multiple years across all three platforms; the per-platform quirks (inotify mask handling, FSEvents event types, ReadDirectoryChangesW overlapped-I/O semantics) are deep enough to make hand-rolling a multi-week investment with no functional payoff. The dep cost (one direct dep, ~5 transitive items withdefault-featuresoff) is bounded and stable.Inner.file: Option<File>plus sentinel-path handling threaded through resize / prefetch / async-flush. Tractable but its own focused milestone.Full Changelog: v0.9.8...v0.9.9
This discussion was created from the release v0.9.9 — Feature complete.
Beta Was this translation helpful? Give feedback.
All reactions