Я довольно новичок в Rust, и я пытался портировать Go веб-сканер, который я сделал для Rust. В Go я создал хэш-карту, которая использовалась (и использовалась совместно) несколькими работниками (go подпрограммы, порождающие одну и ту же функцию). Это было легко решить с помощью мьютексов, но я не могу понять, как сделать то же самое в Rust.
Структура Crawler:
struct Crawler {
client: reqwest::Client,
target: String,
visited: Arc<Mutex<HashSet<String>>>,
queue: Arc<Mutex<Queue<String>>>,
base_url: String,
fetch_any_domain: bool,
workers: u8,
}
В impl
из Crawler Я добавил функцию запуска:
fn run(&self) {
{
match self
.queue
.lock()
.unwrap()
.add(self.convert_link_to_abs(self.target.as_str()))
{
Err(e) => println!("{}", e),
_ => (),
}
}
while self.queue.lock().unwrap().size() > 0 {
match self.queue.lock().unwrap().remove() {
Ok(link) => match self.fetch(link.as_str()) {
Ok(content) => match self.get_links(content) {
Ok(()) => println!("added new links"),
Err(e) => println!("{}", e),
},
Err(e) => println!("{}", e),
},
Err(e) => println!("{}", e),
}
}
}
И я пытался вызвать его одновременно с чем-то вроде этого:
let mut threads = vec![];
let c = Arc::new(Mutex::new(crawler));
for _i in 0..workers {
let cc = c.clone();
threads.push(thread::spawn(move || {
let guard = cc.lock().unwrap();
guard.run();
}));
}
for t in threads {
let _ = t.join();
}
Код каким-то образом запускается, но он застревает почти мгновенно без обработки ничего. Я уверен, что мне просто нужно привыкнуть к подходу Rust, но кто-нибудь может посоветовать, как лучше всего создать многопоточный сканер?
Большое спасибо