У меня есть config
Struct, которым я делюсь в своем приложении actix, например:
pub fn run(addr: &str, pg_pool: PgPool, config: Settings) -> Result<Server, std::io::Error> {
let pool = web::Data::new(pg_pool);
let arc_config = web::Data::new(Arc::new(config)); // <---
let server = HttpServer::new(move || {
App::new()
.service(exhaust)
.app_data(pool.clone())
.app_data(arc_config.clone()) // <---
})
.bind(addr)?
.run();
Затем у меня есть обработчик, который пытается создать несколько потоков и передать эту структуру config
в каждый:
#[get("/exhaust")]
pub async fn exhaust(pool: web::Data<PgPool>, config: web::Data<Arc<Settings>>) -> impl Responder {
for _ in 1..16 {
let handle = thread::spawn(move || {
let inner_config = Arc::clone(&config);
get_single_tweet(inner_config.as_ref().deref(), "1401287393228038149");
});
}
HttpResponse::Ok()
}
Я думал, что, поскольку config
уже обернут в Arc()
, я должен иметь возможность просто Arc::clone()
внутри каждого потока, а затем удалить ссылку в базовой переменной.
Но я получаю эту ошибку:
error[E0382]: use of moved value: `config`
--> src/twitter/routes/pull.rs:63:36
|
58 | pub async fn exhaust(pool: web::Data<PgPool>, config: web::Data<Arc<Settings>>) -> impl Responder {
| ------ move occurs because `config` has type `actix_web::web::Data<Arc<Settings>>`, which does not implement the `Copy` trait
...
63 | let handle = thread::spawn(move || {
| ^^^^^^^ value moved into closure here, in previous iteration of loop
64 | let inner_config = Arc::clone(&config);
| ------ use occurs due to use in closure
Я изо всех сил пытаюсь понять, почему это не удается. Если конфиг находится внутри Arc
, то почему компилятор думает, что я пытаюсь его переместить вместо увеличения счетчика ссылок?
Я также пробовал ряд других подходов, все безуспешно:
- Удаление
move
перед закрытием - компилятор жалуется, что заимствованное значение не живет достаточно долго - Разыменование
config
и перенос его в новыйArc()
- ошибка аналогична исходной
Как правильно это сделать?