diff --git a/src/app/run.rs b/src/app/run.rs index 8241028..bda3d27 100644 --- a/src/app/run.rs +++ b/src/app/run.rs @@ -16,7 +16,9 @@ const FOLDER_REFRESH_INTERVAL: Duration = Duration::from_secs(1); const LOCAL_CHANGE_DEBOUNCE: Duration = Duration::from_millis(750); const PEER_POLL_INTERVAL: Duration = Duration::from_secs(30); const SAFETY_SCAN_INTERVAL: Duration = Duration::from_secs(10 * 60); +const RETRY_BASE_DELAY: Duration = Duration::from_secs(2); const MAX_RETRY_DELAY: Duration = Duration::from_secs(5 * 60); +const MAX_RETRY_EXPONENT: u32 = 8; #[derive(Clone, Debug)] struct RetryState { @@ -249,9 +251,11 @@ fn schedule_retry(retries: &mut BTreeMap, folder_id: Folde } pub(super) fn retry_delay(failure_count: u32) -> Duration { - let exponent = failure_count.saturating_sub(1).min(8); - let seconds = 2_u64 * (1_u64 << exponent); - Duration::from_secs(seconds).min(MAX_RETRY_DELAY) + let exponent = failure_count.saturating_sub(1).min(MAX_RETRY_EXPONENT); + RETRY_BASE_DELAY + .checked_mul(1_u32 << exponent) + .unwrap_or(MAX_RETRY_DELAY) + .min(MAX_RETRY_DELAY) } #[cfg(test)] diff --git a/src/domain/merkle.rs b/src/domain/merkle.rs index 594553f..c146f13 100644 --- a/src/domain/merkle.rs +++ b/src/domain/merkle.rs @@ -5,6 +5,8 @@ use super::{Entry, Manifest, RelativePath, canonical_json_bytes}; const MAX_LEAF_ENTRIES: usize = 64; const BLAKE3_HEX_LENGTH: usize = 64; const ROOT_PREFIX: &str = ""; +#[cfg(test)] +const ENTRIES_ABOVE_LEAF_LIMIT: usize = MAX_LEAF_ENTRIES + 1; #[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)] #[serde(tag = "kind", rename_all = "snake_case")] @@ -143,14 +145,14 @@ fn path_hash(path: &str) -> String { #[cfg(test)] mod tests { - use super::{ManifestMerkleIndex, manifest_merkle_node}; + use super::{ENTRIES_ABOVE_LEAF_LIMIT, ManifestMerkleIndex, manifest_merkle_node}; use crate::domain::{Entry, EntryKind, Manifest}; #[test] fn cached_merkle_nodes_match_the_on_demand_tree() -> anyhow::Result<()> { let folder_id = uuid::Uuid::new_v4(); let mut manifest = Manifest::empty(folder_id); - for number in 0..65 { + for number in 0..ENTRIES_ABOVE_LEAF_LIMIT { let path = format!("file-{number}.txt"); manifest.entries.insert( path.clone(), diff --git a/src/domain/roster.rs b/src/domain/roster.rs index 76f2e36..b814480 100644 --- a/src/domain/roster.rs +++ b/src/domain/roster.rs @@ -6,6 +6,8 @@ use serde::{Deserialize, Serialize}; use super::{DeviceId, FOLDER_PROTOCOL_VERSION, FolderId, canonical_json_bytes}; +const INITIAL_ROSTER_EPOCH: u64 = 1; + #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] pub enum MemberRole { Owner, @@ -46,7 +48,7 @@ impl FolderRoster { folder_id, capability, owner_device_id, - epoch: 1, + epoch: INITIAL_ROSTER_EPOCH, members: BTreeMap::from([(owner.device_id.clone(), owner)]), signature: None, }) diff --git a/src/filesystem.rs b/src/filesystem.rs index 1dcd79a..4f7438f 100644 --- a/src/filesystem.rs +++ b/src/filesystem.rs @@ -11,6 +11,7 @@ use ignore::gitignore::{Gitignore, GitignoreBuilder}; use notify::{EventKind, RecursiveMode, Watcher}; pub const IGNORE_FILE_NAME: &str = ".appaignore"; +const PROCESS_LOCK_FILE_NAME: &str = "appa.lock"; pub struct IgnoreRules { matcher: Gitignore, @@ -142,7 +143,7 @@ pub fn lock_app_process(lock_directory: &Path) -> anyhow::Result { lock_directory.display() ) })?; - let lock_path = lock_directory.join("appa.lock"); + let lock_path = lock_directory.join(PROCESS_LOCK_FILE_NAME); let file = File::create(&lock_path) .with_context(|| format!("could not open Appa process lock {}", lock_path.display()))?; file.try_lock()