-
Notifications
You must be signed in to change notification settings - Fork 101
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for "nowait" mode in file synchronization
- Loading branch information
Showing
34 changed files
with
514 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
use std::{sync::Arc, time::Duration}; | ||
|
||
use server::streaming::persistence::persister::{FilePersister, Persister}; | ||
|
||
use bytes::Bytes; | ||
use iggy::{confirmation::Confirmation, utils::duration::IggyDuration}; | ||
use server::configs::system::SystemConfig; | ||
use tempfile::NamedTempFile; | ||
use tokio::{io::AsyncReadExt, time::sleep}; | ||
|
||
#[tokio::test] | ||
async fn test_append_nowait() { | ||
let config = SystemConfig::default(); | ||
|
||
let temp_out_file = NamedTempFile::new().unwrap(); | ||
let file_path = temp_out_file.path().to_path_buf(); | ||
|
||
let bytes = b"test data"; | ||
|
||
let persister = FilePersister::new(Arc::new(config)).await; | ||
let err = persister | ||
.append( | ||
file_path.to_str().unwrap(), | ||
Bytes::copy_from_slice(bytes), | ||
Some(Confirmation::Nowait), | ||
) | ||
.await; | ||
assert!(err.is_ok()); | ||
|
||
sleep(Duration::from_millis(100)).await; | ||
|
||
let mut file = tokio::fs::File::open(&file_path).await.unwrap(); | ||
let mut buffer = Vec::new(); | ||
file.read_to_end(&mut buffer).await.unwrap(); | ||
|
||
assert_eq!(buffer, bytes); | ||
} | ||
|
||
#[tokio::test] | ||
async fn test_task_removal_on_idle_timeout_and_persistence_of_active_task() { | ||
let mut config = SystemConfig::default(); | ||
config.state.idle_timeout = IggyDuration::new(Duration::from_millis(100)); | ||
|
||
let temp_out_file_1 = NamedTempFile::new().unwrap(); | ||
let file_path_1 = temp_out_file_1.path().to_path_buf(); | ||
let file_path_str_1 = file_path_1.to_str().unwrap(); | ||
|
||
let temp_out_file_2 = NamedTempFile::new().unwrap(); | ||
let file_path_2 = temp_out_file_2.path().to_path_buf(); | ||
let file_path_str_2 = file_path_2.to_str().unwrap(); | ||
|
||
let persister = FilePersister::new(Arc::new(config)).await; | ||
|
||
assert!( | ||
!persister.is_task_active(file_path_str_1), | ||
"Task 1 should not be active initially" | ||
); | ||
assert!( | ||
!persister.is_task_active(file_path_str_2), | ||
"Task 2 should not be active initially" | ||
); | ||
|
||
// Activate the first task by issuing an append command | ||
let err = persister | ||
.append(file_path_str_1, Bytes::new(), Some(Confirmation::Nowait)) | ||
.await; | ||
assert!(err.is_ok()); | ||
assert!( | ||
persister.is_task_active(file_path_str_1), | ||
"Task 1 should be active after appending" | ||
); | ||
|
||
// Wait 50 ms, then activate the second task to refresh its timeout | ||
sleep(Duration::from_millis(50)).await; | ||
let err = persister | ||
.append(file_path_str_2, Bytes::new(), Some(Confirmation::Nowait)) | ||
.await; | ||
assert!(err.is_ok()); | ||
assert!( | ||
persister.is_task_active(file_path_str_2), | ||
"Task 2 should be active after appending" | ||
); | ||
|
||
// Wait another 70 ms, so the total time for the first task (120 ms) exceeds idle_timeout, | ||
// but the second task remains active since its timeout was refreshed | ||
sleep(Duration::from_millis(70)).await; | ||
|
||
// Ensure the second task is still active after its recent append | ||
assert!( | ||
persister.is_task_active(file_path_str_2), | ||
"Task 2 should still be active after recent append" | ||
); | ||
|
||
// Confirm that the first task has been terminated due to idle timeout expiration | ||
assert!( | ||
!persister.is_task_active(file_path_str_1), | ||
"Task 1 should no longer be active after timeout" | ||
); | ||
|
||
// Wait another 150 ms to confirm that the second task also terminates after its own idle timeout | ||
sleep(Duration::from_millis(150)).await; | ||
assert!( | ||
!persister.is_task_active(file_path_str_2), | ||
"Task 2 should no longer be active after idle timeout" | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
use std::{fmt, str::FromStr}; | ||
|
||
use serde::{Deserialize, Serialize}; | ||
|
||
#[derive(Clone, Default, Deserialize, Serialize, Debug)] | ||
pub enum Confirmation { | ||
#[default] | ||
WaitWithFlush, | ||
Wait, | ||
Nowait, | ||
} | ||
|
||
impl FromStr for Confirmation { | ||
type Err = String; | ||
|
||
fn from_str(s: &str) -> Result<Self, Self::Err> { | ||
match s.to_lowercase().as_str() { | ||
"wait_with_flush" => Ok(Confirmation::WaitWithFlush), | ||
"wait" => Ok(Confirmation::Wait), | ||
"nowait" => Ok(Confirmation::Nowait), | ||
_ => Err(format!("Invalid confirmation type: {}", s)), | ||
} | ||
} | ||
} | ||
|
||
impl fmt::Display for Confirmation { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
let s = match self { | ||
Confirmation::WaitWithFlush => "wait_with_flush", | ||
Confirmation::Wait => "wait", | ||
Confirmation::Nowait => "nowait", | ||
}; | ||
write!(f, "{}", s) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.