-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
File transfer example #10
Comments
I'm trying to replace a system where I pipe stdout to/from Trying a naive implementation of pub async fn pull_file(&self, source: &Path, dest: &Path) {
let task = format!("pulling file from {}:{source:?} to {dest:?}", self.address);
tracing::info!("{task}");
let mut channel = self.session.channel_open_session().await.unwrap();
channel.request_subsystem(true, "sftp").await.unwrap();
let sftp = SftpSession::new(channel.into_stream()).await.unwrap();
let mut file = sftp.open(source.to_str().unwrap()).await.unwrap();
let mut dest = File::create(dest)
.await
.map_err(|e| anyhow!(e).context(format!("Failed to read from {source:?}")))
.unwrap();
let mut read = vec![];
file.read_to_end(&mut read)
.await
.unwrap_or_else(|e| panic!("{task} failed to read from local disk with {e:?}"));
tokio::io::AsyncWriteExt::write_all(&mut dest, &read)
.await
.unwrap_or_else(|e| panic!("{task} failed to write to remote server with {e:?}"));
} or pub async fn pull_file(&self, source: &Path, dest: &Path) {
let task = format!("pulling file from {}:{source:?} to {dest:?}", self.address);
tracing::info!("{task}");
let mut channel = self.session.channel_open_session().await.unwrap();
channel.request_subsystem(true, "sftp").await.unwrap();
let sftp = SftpSession::new(channel.into_stream()).await.unwrap();
let mut file = sftp.open(source.to_str().unwrap()).await.unwrap();
let mut dest = File::create(dest)
.await
.map_err(|e| anyhow!(e).context(format!("Failed to read from {source:?}")))
.unwrap();
let mut bytes = vec![0u8; 1024 * 1024];
loop {
let read_count = file
.read(&mut bytes[..])
.await
.unwrap_or_else(|e| panic!("{task} failed to read from local disk with {e:?}"));
if read_count == 0 {
break;
}
tokio::io::AsyncWriteExt::write_all(&mut dest, &bytes[0..read_count])
.await
.unwrap_or_else(|e| panic!("{task} failed to write to remote server with {e:?}"));
}
} is slower than my original |
Hi! Have you tried transferring multiple files? The struct SftpSession doesn't implement clone trait. how can we do this?
|
@rukai I will try to test the speed as soon as possible and provide an example. In addition, I think we need to add a native implementation for high-level. @UVUUUVUU At the moment this is a bottleneck, because internally a mutex is used to process requests, which prevents multitasking from working well. As a temporary solution, you can use
|
Ok, thanks for your answer!Looking forward for your future work. |
how do you want to solve this? could you give some suggestion? |
I think this problem can be solved using a concurrent hashmap because this avoids blocking. the main task is to create a non-blocking list of request/response. flurry may solve this problem, i like their implementation. Oh, by the way, we can just use broadcast, each consumer will only receive his own request. |
The optimization problem should now be resolved with PR #30. Published as
@rukai It would be nice to get feedback from you. |
It would be nice to have an example for how to best transfer a file to/from the remote machine.
e.g. a function like
push_file(source_path: &str, dest_path: &str)
that pushes from the local machine to the remote machine.Doing this efficiently would be complicated since I imagine we would want to read new bytes from the source while sending to the destination?
Additionally this is a very common use case for sftp, so I think making an example of this would bring a lot of value.
The text was updated successfully, but these errors were encountered: