perf: raise the max allowed concurrent connections per SFTP service (#3466)

This commit is contained in:
三咲雅 misaki masa 2025-12-27 07:40:30 +08:00 committed by GitHub
parent 2f66561a82
commit 366fca6b10
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 56 additions and 21 deletions

View file

@ -17,10 +17,11 @@ impl Actor for Close {
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> {
let cmp = &mut cx.core.cmp;
if let Some(item) = cmp.selected().filter(|_| opt.submit).cloned() {
return act!(complete, cx.core.input, CompleteOpt { item, _ticket: cmp.ticket });
return act!(input:complete, cx, CompleteOpt { item, ticket: cmp.ticket });
}
cmp.caches.clear();
cmp.ticket = Default::default();
succ!(render!(mem::replace(&mut cmp.visible, false)));
}
}

View file

@ -29,7 +29,6 @@ impl Actor for Show {
succ!();
};
cmp.ticket = opt.ticket;
cmp.cands = Self::match_candidates(opt.word.as_path(), cache);
if cmp.cands.is_empty() {
succ!(render!(mem::replace(&mut cmp.visible, false)));

View file

@ -5,7 +5,7 @@ use yazi_fs::{path::clean_url, provider::{DirReader, FileHolder}};
use yazi_macro::{act, render, succ};
use yazi_parser::cmp::{CmpItem, ShowOpt, TriggerOpt};
use yazi_proxy::CmpProxy;
use yazi_shared::{AnyAsciiChar, data::Data, natsort, path::{AsPath, PathBufDyn, PathLike}, scheme::{SchemeCow, SchemeLike}, strand::{AsStrand, StrandLike}, url::{UrlBuf, UrlCow, UrlLike}};
use yazi_shared::{AnyAsciiChar, BytePredictor, data::Data, natsort, path::{AsPath, PathBufDyn, PathLike}, scheme::{SchemeCow, SchemeLike}, strand::{AsStrand, StrandLike}, url::{UrlBuf, UrlCow, UrlLike}};
use yazi_vfs::provider;
use crate::{Actor, Ctx};
@ -74,11 +74,14 @@ impl Trigger {
};
let (scheme, path) = SchemeCow::parse(s.as_bytes()).ok()?;
let scheme = scheme.zeroed();
if path.is_empty() && !sep.predicate(s.bytes().last()?) {
return None; // We don't complete a `sftp://test`, but `sftp://test/`
}
// We don't complete a `~`, but `~/`
// Scheme
let scheme = scheme.zeroed();
if scheme.is_local() && path.as_strand() == "~" {
return None;
return None; // We don't complete a `~`, but `~/`
}
// Child
@ -113,7 +116,9 @@ mod tests {
fn test_split() {
yazi_shared::init_tests();
yazi_fs::init();
compare("", "", "");
assert_eq!(Trigger::split_url(""), None);
assert_eq!(Trigger::split_url("sftp://test"), None);
compare(" ", "", " ");
compare("/", "/", "");

View file

@ -0,0 +1,23 @@
use anyhow::Result;
use yazi_macro::{act, succ};
use yazi_parser::input::CompleteOpt;
use yazi_shared::data::Data;
use crate::{Actor, Ctx};
pub struct Complete;
impl Actor for Complete {
type Options = CompleteOpt;
const NAME: &str = "complete";
fn act(cx: &mut Ctx, opt: Self::Options) -> Result<Data> {
let input = &mut cx.input;
if !input.visible || input.ticket.current() != opt.ticket {
succ!();
}
act!(complete, input, opt)
}
}

View file

@ -1 +1 @@
yazi_macro::mod_flat!(close escape show);
yazi_macro::mod_flat!(close complete escape show);

View file

@ -253,7 +253,10 @@ impl<'a> Executor<'a> {
_ => {}
}
}
InputMode::Insert | InputMode::Replace => {}
InputMode::Insert => {
on!(complete);
}
InputMode::Replace => {}
};
self.app.core.input.execute(cmd)

View file

@ -7,7 +7,7 @@ use crate::cmp::CmpItem;
#[derive(Debug)]
pub struct CompleteOpt {
pub item: CmpItem,
pub _ticket: Id, // FIXME: not used
pub ticket: Id,
}
impl TryFrom<CmdCow> for CompleteOpt {
@ -18,7 +18,7 @@ impl TryFrom<CmdCow> for CompleteOpt {
bail!("Invalid 'item' in CompleteOpt");
};
Ok(Self { item, _ticket: c.get("ticket").unwrap_or_default() })
Ok(Self { item, ticket: c.get("ticket").unwrap_or_default() })
}
}

View file

@ -108,7 +108,7 @@ impl AsyncSeek for File {
SeekFrom::End(n) => SeekState::Blocking(
n,
timeout(
Duration::from_secs(10),
Duration::from_secs(45),
self.session.send_sync(requests::Fstat::new(&self.handle))?,
),
),
@ -198,7 +198,7 @@ impl AsyncWrite for File {
if me.flush_rx.is_none() {
match Operator::from(&me.session).fsync(&me.handle) {
Ok(rx) => me.flush_rx = Some(timeout(Duration::from_secs(10), rx)),
Ok(rx) => me.flush_rx = Some(timeout(Duration::from_secs(45), rx)),
Err(Error::Unsupported) => return Poll::Ready(Ok(())),
Err(e) => Err(e)?,
}

View file

@ -55,7 +55,7 @@ impl ReadDir {
let result = self
.session
.send_with_timeout(requests::ReadDir::new(&self.handle), Duration::from_mins(5))
.send_with_timeout(requests::ReadDir::new(&self.handle), Duration::from_mins(45))
.await;
self.name = match result {

View file

@ -1,4 +1,4 @@
use std::{io, sync::Arc};
use std::{io, sync::Arc, time::Duration};
use russh::keys::PrivateKeyWithHashAlg;
use yazi_config::vfs::ServiceSftp;
@ -53,7 +53,14 @@ impl Conn {
use deadpool::managed::PoolError;
let pool = *super::CONN.lock().entry(self.config).or_insert_with(|| {
Box::leak(Box::new(deadpool::managed::Pool::builder(self).max_size(5).build().unwrap()))
Box::leak(Box::new(
deadpool::managed::Pool::builder(self)
.runtime(deadpool::Runtime::Tokio1)
.max_size(8)
.create_timeout(Some(Duration::from_secs(45)))
.build()
.unwrap(),
))
});
pool.get().await.map_err(|e| match e {
@ -67,9 +74,8 @@ impl Conn {
async fn connect(self) -> Result<russh::Channel<russh::client::Msg>, russh::Error> {
let pref = Arc::new(russh::client::Config {
inactivity_timeout: Some(std::time::Duration::from_secs(30)),
inactivity_timeout: Some(std::time::Duration::from_secs(60)),
keepalive_interval: Some(std::time::Duration::from_secs(10)),
nodelay: true,
..Default::default()
});

View file

@ -43,8 +43,6 @@ impl Input {
on!(backspace);
on!(kill);
on!(complete);
}
InputMode::Replace => {}
}