pub enum FsyncPolicy {
Never,
EveryN(u64),
Interval(Duration),
IntervalOrBytes {
period: Duration,
max_bytes: u64,
},
}Expand description
Disk-side fsync policy for persistent RedexFiles.
Governs only the append path on the disk mirror. close() and
explicit RedexFile::sync() calls always fsync regardless of
policy — these are the caller’s explicit durability barriers.
| Policy | Process crash | Kernel / power crash |
|---|---|---|
Never | Loses the tail since last close / sync() | Same |
EveryN(N) | Loses ≤ (N−1) entries from the last sync point | Same |
Interval(d) | Loses ≤ d seconds of writes | Same |
IntervalOrBytes { period, max_bytes } | Loses ≤ min(period of writes, max_bytes of writes) | Same |
Default is FsyncPolicy::Never, matching the pre-FsyncPolicy
behavior — OS page cache only, fsync on close. Callers that need
tighter bounds opt into EveryN, Interval, or
IntervalOrBytes.
Variants§
Never
Never fsync on append. close() still syncs. Lowest latency;
fine for telemetry / best-effort logs.
EveryN(u64)
Fsync after every N successful appends. The fsync runs on a
background task — the appender returns as soon as the bytes
land in the page cache and signals the worker; the worker
runs fsync_all off the hot path. Concurrent notifies during
an in-flight fsync coalesce into a single follow-up.
Worst-case loss bound: (N − 1) entries since the last sync
point, plus the bytes from any fsync that was in flight
when the crash interrupted it. 0 and 1 both collapse to
“signal on every append.”
Under heavy concurrent appends the bound loosens slightly:
the threshold check (fetch_add then if cross { reset })
is not a CAS, so K appenders racing past the threshold can
each cross before any of them resets the counter. The next
sync covers all K of those entries; the durability contract
still holds (no entry survives unsynced past the next
fsync), but the practical bound becomes
(N − 1) + (concurrent appenders at threshold). Pick a
smaller N if you need a tighter bound under contention.
Interval(Duration)
Fsync on a timer, independent of append rate. A per-file
background tokio task drives the sync; close() cancels it.
IntervalOrBytes
Fsync when either period elapses or max_bytes of
writes have accumulated since the last sync, whichever comes
first. The byte threshold counts every byte written to dat,
idx, and ts.
Use this for bursty workloads where a long period would
leave too much data unsynced under load, but a short period
would over-fsync when idle.
Configuration matrix:
period | max_bytes | Behavior |
|---|---|---|
> 0 | > 0 | Full both-arms worker (timer + byte signal) |
> 0 | 0 | Timer-only worker (equivalent to Interval(period)) |
0 | > 0 | Byte-only worker (no timer arm); fsyncs when the byte threshold crosses |
0 | 0 | No worker; equivalent to Never |
The same concurrency caveat as Self::EveryN applies to
the byte arm: K concurrent appenders can each cross the
threshold before any of them resets the counter, so the
effective bound is
max_bytes + (concurrent appenders' bytes at threshold).
Trait Implementations§
Source§impl Clone for FsyncPolicy
impl Clone for FsyncPolicy
Source§fn clone(&self) -> FsyncPolicy
fn clone(&self) -> FsyncPolicy
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for FsyncPolicy
Source§impl Debug for FsyncPolicy
impl Debug for FsyncPolicy
Source§impl Default for FsyncPolicy
impl Default for FsyncPolicy
Source§fn default() -> FsyncPolicy
fn default() -> FsyncPolicy
impl Eq for FsyncPolicy
Source§impl PartialEq for FsyncPolicy
impl PartialEq for FsyncPolicy
Source§fn eq(&self, other: &FsyncPolicy) -> bool
fn eq(&self, other: &FsyncPolicy) -> bool
self and other values to be equal, and is used by ==.impl StructuralPartialEq for FsyncPolicy
Auto Trait Implementations§
impl Freeze for FsyncPolicy
impl RefUnwindSafe for FsyncPolicy
impl Send for FsyncPolicy
impl Sync for FsyncPolicy
impl Unpin for FsyncPolicy
impl UnsafeUnpin for FsyncPolicy
impl UnwindSafe for FsyncPolicy
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.