Push things around so that the chunking process doesn't need to know about pointers
This commit is contained in:
parent
f1b73b28ee
commit
8692d83510
|
@ -9,7 +9,8 @@ use std::path::Path;
|
||||||
use std::process::{Child, Command, Stdio};
|
use std::process::{Child, Command, Stdio};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use yama::commands::{load_pile_descriptor, open_pile};
|
use yama::commands::{load_pile_descriptor, open_pile};
|
||||||
use yama::definitions::TreeNode;
|
use yama::definitions::{PartialPointerData, TreeNode};
|
||||||
|
use yama::operations::storing::{pointer_ops_prepare_to_store, pointers_ops_after_store};
|
||||||
use yama::pile::{Pile, RawPile, StoragePipelineSettings};
|
use yama::pile::{Pile, RawPile, StoragePipelineSettings};
|
||||||
use yama::progress::ProgressTracker;
|
use yama::progress::ProgressTracker;
|
||||||
use yama::remote::responder::{Responder, ResponderWritingPipeline};
|
use yama::remote::responder::{Responder, ResponderWritingPipeline};
|
||||||
|
@ -64,19 +65,15 @@ pub fn chunking<
|
||||||
read: R,
|
read: R,
|
||||||
mut write: W,
|
mut write: W,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
pointer_name: String,
|
|
||||||
tree_node: &TreeNode,
|
tree_node: &TreeNode,
|
||||||
raw_pile: Arc<RP>,
|
raw_pile: Arc<RP>,
|
||||||
parent: Option<String>,
|
|
||||||
progress_bar: PT,
|
progress_bar: PT,
|
||||||
use_writing_pipeline: bool,
|
use_writing_pipeline: bool,
|
||||||
) -> anyhow::Result<(R, W)> {
|
) -> anyhow::Result<(R, W, PartialPointerData)> {
|
||||||
info!("Chunking.");
|
info!("Chunking.");
|
||||||
write_message(&mut write, &"chunk")?;
|
write_message(&mut write, &"chunk")?;
|
||||||
write_message(&mut write, &path)?;
|
write_message(&mut write, &path)?;
|
||||||
write_message(&mut write, &pointer_name)?;
|
|
||||||
write_message(&mut write, tree_node)?;
|
write_message(&mut write, tree_node)?;
|
||||||
write_message(&mut write, &parent)?;
|
|
||||||
write.flush()?;
|
write.flush()?;
|
||||||
|
|
||||||
let (writing_pipeline, control_rx) = if use_writing_pipeline {
|
let (writing_pipeline, control_rx) = if use_writing_pipeline {
|
||||||
|
@ -111,7 +108,7 @@ pub fn chunking<
|
||||||
for handle in join_handles {
|
for handle in join_handles {
|
||||||
handle.join().expect("Join handle should not fail");
|
handle.join().expect("Join handle should not fail");
|
||||||
}
|
}
|
||||||
let read = r_handle.join().unwrap();
|
let mut read = r_handle.join().unwrap();
|
||||||
let write = w_handle.join().unwrap();
|
let write = w_handle.join().unwrap();
|
||||||
|
|
||||||
if let Some(control_rx) = control_rx {
|
if let Some(control_rx) = control_rx {
|
||||||
|
@ -122,7 +119,9 @@ pub fn chunking<
|
||||||
|
|
||||||
info!("Remote finished chunking.");
|
info!("Remote finished chunking.");
|
||||||
|
|
||||||
Ok((read, write))
|
let pointer_data: PartialPointerData = read_message(&mut read)?;
|
||||||
|
|
||||||
|
Ok((read, write, pointer_data))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn quit<R: Read, W: Write>(read: &mut R, write: &mut W) -> anyhow::Result<()> {
|
pub fn quit<R: Read, W: Write>(read: &mut R, write: &mut W) -> anyhow::Result<()> {
|
||||||
|
@ -199,7 +198,7 @@ pub fn backup_remote_source_to_destination<PT: ProgressTracker + Send + 'static>
|
||||||
let scan_result = scanning(&mut read, &mut write, directory.as_ref())?
|
let scan_result = scanning(&mut read, &mut write, directory.as_ref())?
|
||||||
.ok_or_else(|| anyhow!("Remote scan failed (does the directory exist?)"))?;
|
.ok_or_else(|| anyhow!("Remote scan failed (does the directory exist?)"))?;
|
||||||
|
|
||||||
let root =
|
let mut root =
|
||||||
label_filter_and_convert(scan_result, descriptor, desc_path, source_name, dest)?
|
label_filter_and_convert(scan_result, descriptor, desc_path, source_name, dest)?
|
||||||
.ok_or_else(|| anyhow!("Empty filter..."))?;
|
.ok_or_else(|| anyhow!("Empty filter..."))?;
|
||||||
|
|
||||||
|
@ -248,19 +247,27 @@ pub fn backup_remote_source_to_destination<PT: ProgressTracker + Send + 'static>
|
||||||
let raw_pile = Arc::new(pile.raw_pile);
|
let raw_pile = Arc::new(pile.raw_pile);
|
||||||
let pile = Pile::new(raw_pile.clone());
|
let pile = Pile::new(raw_pile.clone());
|
||||||
|
|
||||||
let (mut read, mut write) = chunking(
|
pointer_ops_prepare_to_store(&pile, &mut root, &parent)?;
|
||||||
|
|
||||||
|
info!(
|
||||||
|
"Have pointer_name = {:?}, parent = {:?}",
|
||||||
|
pointer_name, parent
|
||||||
|
);
|
||||||
|
|
||||||
|
let (mut read, mut write, pointer_data) = chunking(
|
||||||
read,
|
read,
|
||||||
write,
|
write,
|
||||||
directory.as_ref(),
|
directory.as_ref(),
|
||||||
pointer_name.clone(),
|
|
||||||
&root,
|
&root,
|
||||||
raw_pile,
|
raw_pile,
|
||||||
parent,
|
|
||||||
progress_bar,
|
progress_bar,
|
||||||
true,
|
true,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
quit(&mut read, &mut write)?;
|
quit(&mut read, &mut write)?;
|
||||||
|
|
||||||
|
pointers_ops_after_store(&pile, &pointer_name, &pointer_data.complete(parent))?;
|
||||||
|
|
||||||
pile.flush()?;
|
pile.flush()?;
|
||||||
|
|
||||||
info!("Stored! Checking for existence...");
|
info!("Stored! Checking for existence...");
|
||||||
|
|
|
@ -1,21 +1,24 @@
|
||||||
// This file implements the responder side of the backup source protocol -- the protocol used
|
// This file implements the responder side of the backup source protocol -- the protocol used
|
||||||
// to connect to remote backup sources.
|
// to connect to remote backup sources.
|
||||||
|
|
||||||
use crate::tree::scan;
|
|
||||||
use anyhow::bail;
|
|
||||||
use crossbeam_channel::Sender;
|
|
||||||
use log::info;
|
|
||||||
use std::io::{stdin, stdout, Read, Write};
|
use std::io::{stdin, stdout, Read, Write};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use yama::definitions::TreeNode;
|
|
||||||
|
use anyhow::bail;
|
||||||
|
use crossbeam_channel::Sender;
|
||||||
|
use log::info;
|
||||||
|
|
||||||
|
use yama::definitions::{PartialPointerData, TreeNode};
|
||||||
use yama::pile::{Pile, RawPile};
|
use yama::pile::{Pile, RawPile};
|
||||||
use yama::progress::ProgressTracker;
|
use yama::progress::ProgressTracker;
|
||||||
use yama::remote::requester::Requester;
|
use yama::remote::requester::Requester;
|
||||||
use yama::remote::{read_message, write_message, RequestBody, ResponseBody};
|
use yama::remote::{read_message, write_message, RequestBody, ResponseBody};
|
||||||
use yama::utils::get_number_of_workers;
|
use yama::utils::get_number_of_workers;
|
||||||
|
|
||||||
|
use crate::tree::scan;
|
||||||
|
|
||||||
pub fn introduction<R: Read, W: Write>(read: &mut R, write: &mut W) -> anyhow::Result<()> {
|
pub fn introduction<R: Read, W: Write>(read: &mut R, write: &mut W) -> anyhow::Result<()> {
|
||||||
let version = env!("CARGO_PKG_VERSION");
|
let version = env!("CARGO_PKG_VERSION");
|
||||||
write_message(
|
write_message(
|
||||||
|
@ -45,41 +48,6 @@ pub fn scanning<R: Read, W: Write>(read: &mut R, write: &mut W) -> anyhow::Resul
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn chunking<R: Read + Send + 'static, W: Write + Send + 'static>(
|
|
||||||
mut read: R,
|
|
||||||
write: W,
|
|
||||||
) -> anyhow::Result<()> {
|
|
||||||
let path: PathBuf = read_message(&mut read)?;
|
|
||||||
let pointer_name: String = read_message(&mut read)?;
|
|
||||||
let tree_node: TreeNode = read_message(&mut read)?;
|
|
||||||
let parent: Option<String> = read_message(&mut read)?;
|
|
||||||
|
|
||||||
let (yama_requester, requester_join_handles) = Requester::new(read, write);
|
|
||||||
|
|
||||||
let raw_pile: Box<dyn RawPile> = Box::new(yama_requester);
|
|
||||||
|
|
||||||
let pile = Pile::new(raw_pile);
|
|
||||||
|
|
||||||
// TODO TODO progress
|
|
||||||
let progress_bar = &mut ();
|
|
||||||
|
|
||||||
yama::operations::storing::store_fully(
|
|
||||||
Arc::new(pile),
|
|
||||||
&path,
|
|
||||||
&pointer_name,
|
|
||||||
tree_node,
|
|
||||||
parent,
|
|
||||||
get_number_of_workers("YAMA_CHUNKERS"),
|
|
||||||
progress_bar,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
for join_handle in requester_join_handles {
|
|
||||||
join_handle.join().expect("Expected to join handle");
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ProgressSender {
|
pub struct ProgressSender {
|
||||||
pub last_sent: Instant,
|
pub last_sent: Instant,
|
||||||
pub current_progress: u64,
|
pub current_progress: u64,
|
||||||
|
@ -128,23 +96,16 @@ impl ProgressTracker for ProgressSender {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn chunking_stdio() -> anyhow::Result<()> {
|
pub fn chunking_stdio() -> anyhow::Result<PartialPointerData> {
|
||||||
let (path, pointer_name, tree_node, parent) = {
|
let (path, tree_node) = {
|
||||||
let stdin = stdin();
|
let stdin = stdin();
|
||||||
let mut read = stdin.lock();
|
let mut read = stdin.lock();
|
||||||
let path: PathBuf = read_message(&mut read)?;
|
let path: PathBuf = read_message(&mut read)?;
|
||||||
let pointer_name: String = read_message(&mut read)?;
|
|
||||||
let tree_node: TreeNode = read_message(&mut read)?;
|
let tree_node: TreeNode = read_message(&mut read)?;
|
||||||
let parent: Option<String> = read_message(&mut read)?;
|
(path, tree_node)
|
||||||
(path, pointer_name, tree_node, parent)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
info!(
|
let (pointer_data, requester_join_handles) = {
|
||||||
"Have pointer_name = {:?}, parent = {:?}",
|
|
||||||
pointer_name, parent
|
|
||||||
);
|
|
||||||
|
|
||||||
let requester_join_handles = {
|
|
||||||
let (yama_requester, requester_join_handles) = Requester::new_from_stdio();
|
let (yama_requester, requester_join_handles) = Requester::new_from_stdio();
|
||||||
let command_sender = yama_requester.clone_command_sender();
|
let command_sender = yama_requester.clone_command_sender();
|
||||||
info!("progress sender in use");
|
info!("progress sender in use");
|
||||||
|
@ -160,17 +121,15 @@ pub fn chunking_stdio() -> anyhow::Result<()> {
|
||||||
|
|
||||||
let pile = Pile::new(raw_pile);
|
let pile = Pile::new(raw_pile);
|
||||||
|
|
||||||
yama::operations::storing::store_fully(
|
let pointer_data = yama::operations::storing::store_without_pointer_ops(
|
||||||
Arc::new(pile),
|
&Arc::new(pile),
|
||||||
&path,
|
&path,
|
||||||
&pointer_name,
|
|
||||||
tree_node,
|
tree_node,
|
||||||
parent,
|
|
||||||
get_number_of_workers("YAMA_CHUNKERS"),
|
get_number_of_workers("YAMA_CHUNKERS"),
|
||||||
&mut progress_bar,
|
&mut progress_bar,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
requester_join_handles
|
(pointer_data, requester_join_handles)
|
||||||
};
|
};
|
||||||
|
|
||||||
info!("Waiting to join.");
|
info!("Waiting to join.");
|
||||||
|
@ -181,20 +140,7 @@ pub fn chunking_stdio() -> anyhow::Result<()> {
|
||||||
|
|
||||||
info!("Chunking completed.");
|
info!("Chunking completed.");
|
||||||
|
|
||||||
Ok(())
|
Ok(pointer_data)
|
||||||
}
|
|
||||||
|
|
||||||
pub fn handler<R: Read + Send + 'static, W: Write + Send + 'static>(
|
|
||||||
mut read: R,
|
|
||||||
mut write: W,
|
|
||||||
) -> anyhow::Result<()> {
|
|
||||||
introduction(&mut read, &mut write)?;
|
|
||||||
|
|
||||||
scanning(&mut read, &mut write)?;
|
|
||||||
|
|
||||||
chunking(read, write)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handler_stdio() -> anyhow::Result<()> {
|
pub fn handler_stdio() -> anyhow::Result<()> {
|
||||||
|
@ -217,9 +163,10 @@ pub fn handler_stdio() -> anyhow::Result<()> {
|
||||||
info!("Chunking.");
|
info!("Chunking.");
|
||||||
drop(read);
|
drop(read);
|
||||||
drop(write);
|
drop(write);
|
||||||
chunking_stdio()?;
|
let pointer_data = chunking_stdio()?;
|
||||||
read = stdin.lock();
|
read = stdin.lock();
|
||||||
write = stdout.lock();
|
write = stdout.lock();
|
||||||
|
write_message(&mut write, &pointer_data)?;
|
||||||
}
|
}
|
||||||
"exit" => {
|
"exit" => {
|
||||||
write_message(&mut write, &"exit")?;
|
write_message(&mut write, &"exit")?;
|
||||||
|
|
|
@ -35,6 +35,24 @@ pub struct PointerData {
|
||||||
pub gid_lookup: BTreeMap<u16, Option<String>>,
|
pub gid_lookup: BTreeMap<u16, Option<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct PartialPointerData {
|
||||||
|
pub chunk_ref: RecursiveChunkRef,
|
||||||
|
pub uid_lookup: BTreeMap<u16, Option<String>>,
|
||||||
|
pub gid_lookup: BTreeMap<u16, Option<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialPointerData {
|
||||||
|
pub fn complete(self, parent_pointer: Option<String>) -> PointerData {
|
||||||
|
PointerData {
|
||||||
|
chunk_ref: self.chunk_ref,
|
||||||
|
parent_pointer,
|
||||||
|
uid_lookup: self.uid_lookup,
|
||||||
|
gid_lookup: self.gid_lookup,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
|
#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
|
||||||
pub struct RecursiveChunkRef {
|
pub struct RecursiveChunkRef {
|
||||||
/// The root Chunk ID.
|
/// The root Chunk ID.
|
||||||
|
|
|
@ -29,7 +29,9 @@ use log::{error, warn};
|
||||||
use crate::chunking::{ChunkSubmissionTarget, RecursiveChunker, SENSIBLE_THRESHOLD};
|
use crate::chunking::{ChunkSubmissionTarget, RecursiveChunker, SENSIBLE_THRESHOLD};
|
||||||
use crate::commands;
|
use crate::commands;
|
||||||
use crate::commands::{fully_integrate_pointer_node, retrieve_tree_node};
|
use crate::commands::{fully_integrate_pointer_node, retrieve_tree_node};
|
||||||
use crate::definitions::{PointerData, RecursiveChunkRef, RootTreeNode, TreeNode};
|
use crate::definitions::{
|
||||||
|
PartialPointerData, PointerData, RecursiveChunkRef, RootTreeNode, TreeNode,
|
||||||
|
};
|
||||||
use crate::pile::{existence_checker_stage, Pile, RawPile, StoragePipelineSettings};
|
use crate::pile::{existence_checker_stage, Pile, RawPile, StoragePipelineSettings};
|
||||||
use crate::progress::ProgressTracker;
|
use crate::progress::ProgressTracker;
|
||||||
use crate::tree::{create_uidgid_lookup_tables, differentiate_node_in_place};
|
use crate::tree::{create_uidgid_lookup_tables, differentiate_node_in_place};
|
||||||
|
@ -242,21 +244,16 @@ pub fn store_fully<PT: ProgressTracker>(
|
||||||
progress_bar: &mut PT,
|
progress_bar: &mut PT,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
pointer_ops_prepare_to_store(&pile, &mut root_node, &parent)?;
|
pointer_ops_prepare_to_store(&pile, &mut root_node, &parent)?;
|
||||||
let pointer_data = store_without_pointer_ops(
|
let pointer_data =
|
||||||
&pile,
|
store_without_pointer_ops(&pile, &root_dir, root_node, num_workers, progress_bar)?
|
||||||
&root_dir,
|
.complete(parent);
|
||||||
root_node,
|
pointers_ops_after_store(&pile, &new_pointer_name, &pointer_data)?;
|
||||||
parent,
|
|
||||||
num_workers,
|
|
||||||
progress_bar,
|
|
||||||
)?;
|
|
||||||
pointers_ops_after_store(pile, &new_pointer_name, &pointer_data)?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pointers_ops_after_store(
|
pub fn pointers_ops_after_store(
|
||||||
pile: Arc<Pile<Box<dyn RawPile>>>,
|
pile: &Pile<impl RawPile>,
|
||||||
new_pointer_name: &&String,
|
new_pointer_name: &str,
|
||||||
pointer_data: &PointerData,
|
pointer_data: &PointerData,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
pile.write_pointer(&new_pointer_name, &pointer_data)?;
|
pile.write_pointer(&new_pointer_name, &pointer_data)?;
|
||||||
|
@ -265,7 +262,7 @@ pub fn pointers_ops_after_store(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pointer_ops_prepare_to_store(
|
pub fn pointer_ops_prepare_to_store(
|
||||||
pile: &Arc<Pile<Box<dyn RawPile>>>,
|
pile: &Pile<impl RawPile>,
|
||||||
mut root_node: &mut TreeNode,
|
mut root_node: &mut TreeNode,
|
||||||
parent: &Option<String>,
|
parent: &Option<String>,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
|
@ -288,10 +285,9 @@ pub fn store_without_pointer_ops<PT: ProgressTracker>(
|
||||||
pile: &Arc<Pile<Box<dyn RawPile>>>,
|
pile: &Arc<Pile<Box<dyn RawPile>>>,
|
||||||
root_dir: &PathBuf,
|
root_dir: &PathBuf,
|
||||||
mut root_node: TreeNode,
|
mut root_node: TreeNode,
|
||||||
parent: Option<String>,
|
|
||||||
num_workers: u8,
|
num_workers: u8,
|
||||||
progress_bar: &mut PT,
|
progress_bar: &mut PT,
|
||||||
) -> anyhow::Result<PointerData> {
|
) -> anyhow::Result<PartialPointerData> {
|
||||||
// TODO make these configurable
|
// TODO make these configurable
|
||||||
let sps = StoragePipelineSettings {
|
let sps = StoragePipelineSettings {
|
||||||
num_compressors: get_number_of_workers("YAMA_PL_COMPRESSORS") as u32,
|
num_compressors: get_number_of_workers("YAMA_PL_COMPRESSORS") as u32,
|
||||||
|
@ -332,9 +328,8 @@ pub fn store_without_pointer_ops<PT: ProgressTracker>(
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let pointer_data = PointerData {
|
let pointer_data = PartialPointerData {
|
||||||
chunk_ref,
|
chunk_ref,
|
||||||
parent_pointer: parent,
|
|
||||||
uid_lookup,
|
uid_lookup,
|
||||||
gid_lookup,
|
gid_lookup,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue