[wip] retry chunks
- make `Chunk` lifetime agnostic by using a raw pointer
- add `fn Uploading::rewind`
- add `fn AppState::{next_chunk, is_done}`
This commit is contained in:
parent
5556a658f5
commit
f05e112040
3 changed files with 57 additions and 27 deletions
|
|
@ -8,11 +8,13 @@ use console::style;
|
|||
use indicatif::{ProgressBar, ProgressStyle};
|
||||
use log::{debug, warn};
|
||||
|
||||
use crate::file::Chunk;
|
||||
|
||||
use super::{
|
||||
cachefile::CacheFile,
|
||||
cli::Cli,
|
||||
file::{self, FileTrait},
|
||||
sharry::{self, Client, ClientError},
|
||||
sharry::{self, Client},
|
||||
};
|
||||
|
||||
pub struct AppState {
|
||||
|
|
@ -112,31 +114,32 @@ impl AppState {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn upload_chunk(&mut self) -> sharry::Result<bool> {
|
||||
fn next_chunk(&mut self) -> io::Result<Option<Chunk>> {
|
||||
let Some(mut uploading) = self.inner.pop_file(&self.http) else {
|
||||
self.inner
|
||||
.share_notify(&self.http)
|
||||
.unwrap_or_else(|e| warn!("Failed to notify the share: {e}"));
|
||||
|
||||
return Ok(true);
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
debug!("{uploading:?}");
|
||||
|
||||
self.get_or_create_progressbar(&uploading);
|
||||
|
||||
let chunk = uploading
|
||||
.read(&mut self.buffer)
|
||||
.map_err(ClientError::from)?;
|
||||
let chunk = uploading.read(&mut self.buffer);
|
||||
self.inner.push_file(uploading);
|
||||
let chunk = chunk?;
|
||||
|
||||
debug!("{chunk:?}");
|
||||
|
||||
self.http.file_patch(
|
||||
chunk.get_patch_uri(),
|
||||
self.inner.alias_id(),
|
||||
chunk.get_offset(),
|
||||
chunk.get_data(),
|
||||
)?;
|
||||
Ok(Some(chunk))
|
||||
}
|
||||
|
||||
fn is_done(&mut self) -> bool {
|
||||
let Some(uploading) = self.inner.pop_file(&self.http) else {
|
||||
return true;
|
||||
};
|
||||
|
||||
match uploading.check_eof() {
|
||||
Ok(uploading) => {
|
||||
|
|
@ -148,15 +151,29 @@ impl AppState {
|
|||
drop(bar);
|
||||
|
||||
self.inner.push_file(uploading);
|
||||
Ok(false)
|
||||
}
|
||||
Err(path) => {
|
||||
debug!("Finished {:?}!", path.display());
|
||||
self.finish_progressbar();
|
||||
}
|
||||
}
|
||||
|
||||
Ok(self.inner.is_empty())
|
||||
}
|
||||
self.inner.is_empty()
|
||||
}
|
||||
|
||||
pub fn upload_chunk(&mut self) -> sharry::Result<bool> {
|
||||
let Some(chunk) = self.next_chunk()? else {
|
||||
return Ok(true);
|
||||
};
|
||||
|
||||
self.http.file_patch(
|
||||
chunk.get_patch_uri(),
|
||||
self.inner.alias_id(),
|
||||
chunk.get_offset(),
|
||||
unsafe { chunk.get_data() },
|
||||
)?;
|
||||
|
||||
Ok(self.is_done())
|
||||
}
|
||||
|
||||
pub fn file_names(&self) -> Vec<&str> {
|
||||
|
|
|
|||
|
|
@ -1,23 +1,25 @@
|
|||
use std::fmt;
|
||||
|
||||
pub struct Chunk<'t> {
|
||||
data: &'t [u8],
|
||||
patch_uri: &'t str,
|
||||
pub struct Chunk {
|
||||
data: *const [u8],
|
||||
patch_uri: String,
|
||||
offset: u64,
|
||||
}
|
||||
|
||||
impl fmt::Debug for Chunk<'_> {
|
||||
impl fmt::Debug for Chunk {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("Chunk")
|
||||
.field("patch_uri", &self.patch_uri)
|
||||
.field("offset", &self.offset)
|
||||
.field("data.len()", &self.data.len())
|
||||
.field("data_len", &self.data.len())
|
||||
.finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'t> Chunk<'t> {
|
||||
pub fn new(data: &'t [u8], patch_uri: &'t str, offset: u64) -> Self {
|
||||
impl Chunk {
|
||||
pub fn new(data: &[u8], patch_uri: String, offset: u64) -> Self {
|
||||
let data: *const [u8] = data as *const [u8];
|
||||
|
||||
Self {
|
||||
data,
|
||||
patch_uri,
|
||||
|
|
@ -25,8 +27,8 @@ impl<'t> Chunk<'t> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_data(&self) -> &[u8] {
|
||||
self.data
|
||||
pub unsafe fn get_data(&self) -> &[u8] {
|
||||
unsafe { &*self.data }
|
||||
}
|
||||
|
||||
pub fn get_length(&self) -> u64 {
|
||||
|
|
@ -39,7 +41,7 @@ impl<'t> Chunk<'t> {
|
|||
}
|
||||
|
||||
pub fn get_patch_uri(&self) -> &str {
|
||||
self.patch_uri
|
||||
&self.patch_uri
|
||||
}
|
||||
|
||||
pub fn get_offset(&self) -> u64 {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ pub struct Uploading {
|
|||
path: PathBuf,
|
||||
size: u64,
|
||||
patch_uri: String,
|
||||
last_offset: Option<u64>,
|
||||
offset: u64,
|
||||
}
|
||||
|
||||
|
|
@ -34,6 +35,7 @@ impl Uploading {
|
|||
path,
|
||||
size,
|
||||
patch_uri,
|
||||
last_offset: None,
|
||||
offset: 0,
|
||||
}
|
||||
}
|
||||
|
|
@ -42,7 +44,15 @@ impl Uploading {
|
|||
self.offset
|
||||
}
|
||||
|
||||
pub fn read<'t>(&'t mut self, buf: &'t mut [u8]) -> io::Result<Chunk<'t>> {
|
||||
pub fn rewind(self) -> Option<Self> {
|
||||
self.last_offset.map(|last_offset| Self {
|
||||
last_offset: None,
|
||||
offset: last_offset,
|
||||
..self
|
||||
})
|
||||
}
|
||||
|
||||
pub fn read(&mut self, buf: &mut [u8]) -> io::Result<Chunk> {
|
||||
let mut f = fs::File::open(&self.path)?;
|
||||
|
||||
f.seek(SeekFrom::Start(self.offset))?;
|
||||
|
|
@ -55,7 +65,8 @@ impl Uploading {
|
|||
));
|
||||
}
|
||||
|
||||
let chunk = Chunk::new(&buf[..read_len], &self.patch_uri, self.offset);
|
||||
let chunk = Chunk::new(&buf[..read_len], self.patch_uri.clone(), self.offset);
|
||||
self.last_offset = Some(self.offset);
|
||||
self.offset += chunk.get_length();
|
||||
|
||||
Ok(chunk)
|
||||
|
|
|
|||
Loading…
Reference in a new issue