Skip to content

Commit

Permalink
fix: implement lazy reading to prevent avoid fd limit
Browse files Browse the repository at this point in the history
drawback: through put reduced to 50%

Signed-off-by: ClSlaid <[email protected]>
  • Loading branch information
ClSlaid committed Oct 28, 2023
1 parent 251245d commit 7a80272
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 36 deletions.
48 changes: 37 additions & 11 deletions libs/clipboard/src/platform/linux/local_file.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use std::{
collections::HashSet, fs::File, os::unix::prelude::PermissionsExt, path::PathBuf,
collections::HashSet,
fs::File,
io::{Read, Seek},
os::unix::prelude::PermissionsExt,
path::PathBuf,
time::SystemTime,
};

Expand Down Expand Up @@ -63,16 +67,8 @@ impl LocalFile {
.trim_start_matches('/')
.replace('/', "\\");

let handle = if is_dir {
None
} else {
let file = std::fs::File::open(path).map_err(|e| CliprdrError::FileError {
path: path.clone(),
err: e,
})?;
let reader = file;
Some(reader)
};
// NOTE: open files lazily
let handle = None;

Ok(Self {
name,
Expand Down Expand Up @@ -163,6 +159,36 @@ impl LocalFile {

buf.to_vec()
}

pub fn read_exact_at(&mut self, buf: &mut [u8], offset: u64) -> Result<(), CliprdrError> {
if self.handle.is_none() {
let handle = std::fs::File::open(&self.path).map_err(|e| CliprdrError::FileError {
path: self.path.clone(),
err: e,
})?;
self.handle = Some(handle);
};

let handle = self.handle.as_mut().unwrap();

handle
.seek(std::io::SeekFrom::Start(offset))
.map_err(|e| CliprdrError::FileError {
path: self.path.clone(),
err: e,
})?;
handle
.read_exact(buf)
.map_err(|e| CliprdrError::FileError {
path: self.path.clone(),
err: e,
})?;
// gc
if offset + (buf.len() as u64) >= self.size {
self.handle = None;
}
Ok(())
}
}

pub(super) fn construct_file_list(paths: &[PathBuf]) -> Result<Vec<LocalFile>, CliprdrError> {
Expand Down
28 changes: 3 additions & 25 deletions libs/clipboard/src/platform/linux/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::{
os::unix::prelude::FileExt,
path::PathBuf,
sync::{mpsc::Sender, Arc},
time::Duration,
Expand Down Expand Up @@ -189,7 +188,7 @@ impl ClipboardContext {
conn_id: i32,
request: FileContentsRequest,
) -> Result<(), CliprdrError> {
let file_list = self.local_files.lock();
let mut file_list = self.local_files.lock();

let file_contents_resp = match request {
FileContentsRequest::Size {
Expand Down Expand Up @@ -239,7 +238,7 @@ impl ClipboardContext {
length,
conn_id
);
let Some(file) = file_list.get(file_idx) else {
let Some(file) = file_list.get_mut(file_idx) else {
log::error!(
"invalid file index {} requested from conn: {}",
file_idx,
Expand All @@ -260,22 +259,6 @@ impl ClipboardContext {
file.name
);

let Some(handle) = &file.handle else {
log::error!(
"invalid file index {} requested from conn: {}",
file_idx,
conn_id
);
resp_file_contents_fail(conn_id, stream_id);

return Err(CliprdrError::InvalidRequest {
description: format!(
"request to read directory on index {} as file from conn: {}",
file_idx, conn_id
),
});
};

if offset > file.size {
log::error!("invalid reading offset requested from conn: {}", conn_id);
resp_file_contents_fail(conn_id, stream_id);
Expand All @@ -295,12 +278,7 @@ impl ClipboardContext {

let mut buf = vec![0u8; read_size as usize];

handle
.read_exact_at(&mut buf, offset)
.map_err(|e| CliprdrError::FileError {
path: file.path.clone(),
err: e,
})?;
file.read_exact_at(&mut buf, offset)?;

ClipboardFile::FileContentsResponse {
msg_flags: 0x1,
Expand Down

0 comments on commit 7a80272

Please sign in to comment.