From 016c34fbe86b52862e7b938a3aa3dba5e87d864d Mon Sep 17 00:00:00 2001 From: bitful-pannul Date: Fri, 8 Nov 2024 21:42:48 +0400 Subject: [PATCH] app_store ft_worker: do not create received zip file before first chunk --- .../packages/app_store/ft_worker/src/lib.rs | 53 +++++++++++-------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/kinode/packages/app_store/ft_worker/src/lib.rs b/kinode/packages/app_store/ft_worker/src/lib.rs index b4f2b3ec..9c80ae2c 100644 --- a/kinode/packages/app_store/ft_worker/src/lib.rs +++ b/kinode/packages/app_store/ft_worker/src/lib.rs @@ -78,6 +78,7 @@ fn init(our: Address) { } // killswitch timer, 2 minutes. sender or receiver gets killed/cleaned up. + // TODO: killswitch update bubbles up to downloads process? timer::set_timer(120000, None); let start = std::time::Instant::now(); @@ -167,7 +168,11 @@ fn handle_receiver( package_id: &PackageId, version_hash: &str, ) -> anyhow::Result<()> { - // TODO: write to a temporary location first, then check hash as we go, then rename to final location. + let timer_address = Address::from_str("our@timer:distro:sys")?; + + let mut file: Option = None; + let mut size: Option = None; + let mut hasher = Sha256::new(); let package_dir = vfs::open_dir( &format!( @@ -179,16 +184,6 @@ fn handle_receiver( None, )?; - let timer_address = Address::from_str("our@timer:distro:sys")?; - - let mut file = vfs::open_file( - &format!("{}{}.zip", &package_dir.path, version_hash), - true, - None, - )?; - let mut size: Option = None; - let mut hasher = Sha256::new(); - loop { let message = await_message()?; if *message.source() == timer_address { @@ -200,7 +195,28 @@ fn handle_receiver( match message.body().try_into()? { DownloadRequests::Chunk(chunk) => { - handle_chunk(&mut file, &chunk, parent_process, &mut size, &mut hasher)?; + let bytes = if let Some(blob) = get_blob() { + blob.bytes + } else { + return Err(anyhow::anyhow!("ft_worker: got no blob in chunk request")); + }; + + if file.is_none() { + file = Some(vfs::open_file( + &format!("{}{}.zip", &package_dir.path, version_hash), + true, + None, + )?); + } + + handle_chunk( + file.as_mut().unwrap(), + &chunk, + parent_process, + &mut size, + &mut hasher, + &bytes, + )?; if let Some(s) = size { if chunk.offset + chunk.length >= s { let recieved_hash = format!("{:x}", hasher.finalize()); @@ -232,7 +248,7 @@ fn handle_receiver( let manifest_filename = format!("{}{}.json", package_dir.path, version_hash); - let contents = file.read()?; + let contents = file.as_mut().unwrap().read()?; extract_and_write_manifest(&contents, &manifest_filename)?; Request::new() @@ -292,15 +308,10 @@ fn handle_chunk( parent: &Address, size: &mut Option, hasher: &mut Sha256, + bytes: &[u8], ) -> anyhow::Result<()> { - let bytes = if let Some(blob) = get_blob() { - blob.bytes - } else { - return Err(anyhow::anyhow!("ft_worker: got no blob")); - }; - - file.write_all(&bytes)?; - hasher.update(&bytes); + file.write_all(bytes)?; + hasher.update(bytes); if let Some(total_size) = size { // let progress = ((chunk.offset + chunk.length) as f64 / *total_size as f64 * 100.0) as u64;