pub struct RenameWithRetryStrategy {}Expand description
RenameWithRetryStrategy uses the Standard Library rename function to transition the
working file to the target file and retries if that fails with a PermissionDenied error.
The other commit strategy available is SimpleRenameStrategy.
For POSIX systems and Windows systems in which there is no contention for the target file,
SimpleRenameStrategy is a good choice. For Windows systems in which two or more threads are
simultaneously trying to update the target, RenameWithRetryStrategy is a good choice.
This crate provides a ready-to-use RenameWithRetryStrategy instance named
RENAME_WITH_RETRY_STRATEGY.
By default, the SimpleRenameStrategy commit strategy is used.
This retry strategy has been shown to work well with Windows 10 and Windows 11 on local SSD drives and with a NAS using as many as 10 threads contending for the target file…
- Use a “jitter” between 0 and 15 to avoid threads being synchronized during contention
- Calculate a “base sleep” value: 11 + (3 * jitter)
- Try to commit
- If that succeeds then we’re done
- If that fails with any error except
PermissionDeniedthen return that error - Otherwise sleep for the base sleep value multiplied by the try count. For example…
- If the jitter is 1
- Then the base sleep is 11 + (3 * 1) = 14
- For the first try, this strategy would sleep for 14 * 1 milliseconds
- For the second try, this strategy would sleep for 14 * 2 milleconds
- Until 7 attempts have been made at which point the
PermissionDeniederror is returned.
In the worst case, this strategy sleeps for a total of (11 + (3 * 15)) * (7 * (7+1) / 2) = 1568 milliseconds.
§Example
use phazer::{PhazerBuilder, RENAME_WITH_RETRY_STRATEGY};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let phazer = PhazerBuilder::with_target("uses-rename-with-retry-strategy.txt")
.commit_strategy(RENAME_WITH_RETRY_STRATEGY)
.build();
// Build the working file
// `rename` is called to transition the working file to the target
phazer.commit()?;
Ok(())
}