Пожалуйста, примите во внимание этот код ржавчины,
use scoped_threadpool::Pool;
use std::thread;
const BASE_URL: &str = "https://www.bing.com/search?q=";
struct my_struct<'a> {
url: &'a str,
id: i16,
}
impl my_struct<'_> {
fn doGet(&self) -> bool {
let resp = ureq::get(self.url).timeout_connect(5_000).call();
if !resp.ok() {
return false;
} else {
return resp.ok();
}
}
}
fn main() {
println!("Hello, world!");
let our_vec = (1..11).collect::<Vec<_>>();
let mut pool = Pool::new(3);
pool.scoped(|scoped| {
for entry in our_vec {
scoped.execute(move || {
let url = format!("{}{}", BASE_URL, entry);
let this_item = my_struct {
url: &url,
id: entry,
};
let our_bool = this_item.doGet();
println!("{} status: {}", entry, our_bool);
});
}
});
}
Он генерирует 10 URL-адресов и делает минимальный GET
для каждого, и это работает. Тем не менее, приведенный выше код использует новое соединение для каждого URL-адреса, и, следовательно, слишком дорого для моей реальной ситуации. ureq
, кажется, имеет Агент , который поддерживает пул соединений.
Итак, я попытался:
const BASE_URL: &str = "https://www.bing.com/search?q=";
use scoped_threadpool::Pool;
use std::thread;
struct my_struct<'a> {
url: &'a str,
id: i16,
}
impl my_struct<'_> {
fn doGet(&self) -> bool {
let resp = ureq::get(self.url).timeout_connect(5_000).call();
if !resp.ok() {
return false;
} else {
return resp.ok();
}
}
fn doGet_withAgent(&self, some_Agent: &ureq::Agent) -> bool {
return true;
}
}
fn main() {
println!("Hello, world!");
let our_vec = (1..11).collect::<Vec<_>>();
let mut pool = Pool::new(3);
let agent = ureq::Agent::new();
pool.scoped(|scoped| {
for entry in our_vec {
scoped.execute(move || {
let url = format!("{}{}", BASE_URL, 3);
let this_item = my_struct {
url: &url,
id: entry,
};
//let our_bool = this_item.doGet();
let our_bool = this_item.doGet_withAgent(&agent);
println!("{} status: {}", entry, our_bool);
});
}
});
}
, но не могу понять, что это правильно:
error[E0382]: use of moved value: `agent`
--> src/main.rs:33:28
|
33 | scoped.execute(move || {
| ^^^^^^^ value moved into closure here, in previous iteration of loop
...
40 | let our_bool = this_item.doGet_withAgent(&agent);
| ----- use occurs due to use in closure
Моя цель - повторно использовать мои соединения. Какой идиоматический c способ добиться этого?
Редактировать 1
const BASE_URL: &str = "https://www.bing.com/search?q=";
use scoped_threadpool::Pool;
use std::thread;
struct my_struct<'a> {
url: &'a str,
id: i16,
}
impl my_struct<'_> {
fn doGet(&self) -> bool {
let resp = ureq::get(self.url).timeout_connect(5_000).call();
if !resp.ok() {
return false;
} else {
return resp.ok();
}
}
fn doGet_withAgent(&self, some_Agent: &ureq::Agent) -> bool {
let resp = some_Agent.get(self.url).timeout_connect(5_000).call();
return true;
}
}
fn main() {
println!("Hello, world!");
let our_vec = (1..11).collect::<Vec<_>>();
let mut pool = Pool::new(3);
let mut agent = ureq::Agent::new();
pool.scoped(|scoped| {
for entry in our_vec {
let agent = &agent;
scoped.execute(move || {
let url = format!("{}{}", BASE_URL, entry);
let this_item = my_struct {
url: &url,
id: entry,
};
let our_bool = this_item.doGet_withAgent(agent);
println!("{} status: {}", entry, our_bool);
});
}
});
}
Редактировать 2
Поэтому я завернул агент в ARC
, все еще используя новые соединения для последовательных запросов.
const BASE_URL: &str = "https://www.google.com/search?q=";
use scoped_threadpool::Pool;
use std::sync::Arc;
use std::sync::Mutex;
use std::thread;
struct my_struct<'a> {
url: &'a str,
id: i16,
}
impl my_struct<'_> {
fn doGet(&self) -> bool {
let resp = ureq::get(self.url).timeout_connect(5_000).call();
return resp.ok();
}
//fn doGet_withAgent(&self, some_Agent: ureq::Agent) -> bool {
//fn doGet_withAgent(&self, some_mutex: &std::sync::Arc)-> bool{
fn doGet_withAgent(&self, some_mutex: Arc<Mutex<ureq::Agent>>) -> bool {
let mut guard = some_mutex.lock().unwrap();
let resp = guard.head(self.url).timeout_connect(5_000).call();
return resp.ok();
}
}
fn main() {
println!("Hello, world!");
let our_vec = (1..11).collect::<Vec<_>>();
let mut pool = Pool::new(3);
let agent = Arc::new(Mutex::new(ureq::Agent::new()));
pool.scoped(|scoped| {
for entry in our_vec {
let agent_clone = agent.clone();
scoped.execute(move || {
let url = format!("{}{}", BASE_URL, 3);
let this_item = my_struct {
url: &url,
id: entry,
};
let our_bool = this_item.doGet_withAgent(agent_clone);
println!("{} status: {}", entry, our_bool);
});
}
});
}