Я пишу программу, которая выполняет команду на сервере, используя s sh и получает вывод.
Часть, которую я не понимаю, ниже в коде.
Если функция ждет, а затем возвращает строку, она работает как положено, но если работает с TCP, она начинает работать очень плохо. Я ожидаю, что использование 100 потоков на 100 хостах будет работать в 100 раз быстрее, потому что одновременно откроются 100 сокетов.
В спящем варианте изменение poolThreads
напрямую влияет на время выполнения. В версии с потоками TCP изменение pool
с 1 на 100 с 100 хостами только ускоряет его с 90 до 67, потому что некоторые хосты отключены.
Я читаю документацию, но не могу найти ничего, что могло бы мне помочь .
use clap::{App, Arg};
use rayon::prelude::*;
use rayon::ThreadPoolBuilder;
use ssh2::Session;
use std::fmt::Display;
use std::io::prelude::*;
use std::io::{BufReader, Read};
use std::net::{TcpStream, ToSocketAddrs};
use std::thread::sleep;
use std::time::Duration;
fn process_host<A>(hostname: A) -> Result<String, String>
where
A: ToSocketAddrs + Display,
{
sleep(Duration::from_secs(1));
return Ok(hostname.to_string());
// here is the problem
// -----------------------------------------------------------
let tcp = match TcpStream::connect(&hostname) {
Ok(a) => a,
Err(e) => {
return Err(format!("{}:{}", hostname, e).to_string());
}
};
let mut sess = match Session::new() {
Ok(a) => a,
Err(e) => {
// todo logging
return Err(format!("{}:{}", hostname, e).to_string());
}
};
sess.set_tcp_stream(tcp);
match sess.handshake() {
Ok(a) => a,
Err(e) => {
return Err(format!("{}:{}", hostname, e).to_string());
}
};
Ok(format!("{}", hostname))
}
fn main() {
let hosts = vec!["aaaaa:22", "bbbbbbb:22"];
let pool = ThreadPoolBuilder::new()
.num_threads(10)
.build()
.expect("failed creating pool");
pool.install(|| {
hosts
.par_iter()
.map(|x| process_host(x))
.for_each(|x| println!("{:?}", x))
});
}