I have a code I want to refactor to avoid duplication (input
variable duplicated). The issue is that I cannot use short version of the code because it became not Sent. The code below works:
fn handle_ai(
&mut self,
mut output_sender: Sender<Vec<u8>>,
mut message_income: MessageIncome
) -> JoinHandle<()> {
let session = Arc::clone(&self.session);
let data_storage = Arc::clone(&self.data_storage);
let mut movement_ai = MovementAI::new();
let mut fighting_ai = FightingAI::new();
tokio::spawn(async move {
loop {
let input = AIManagerInput {
session: Arc::clone(&session),
data_storage: Arc::clone(&data_storage),
output_sender: output_sender.clone(),
message_income: message_income.clone(),
};
movement_ai.manage(input).await;
let input = AIManagerInput {
session: Arc::clone(&session),
data_storage: Arc::clone(&data_storage),
output_sender: output_sender.clone(),
message_income: message_income.clone(),
};
fighting_ai.manage(input).await;
}
})
}
When I try to pass input like below:
movement_ai.manage(AIManagerInput {
session: Arc::clone(&session),
data_storage: Arc::clone(&data_storage),
output_sender: output_sender.clone(),
message_income: message_income.clone(),
}).await;
I got an error:
error: future cannot be sent between threads safely
--> src\client\mod.rs:313:9
|
313 | tokio::spawn(async move {
| ^^^^^^^^^^^^ future created by async block is not `Send`
|
= help: within `MessageIncome`, the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Sender<IncomeMessageType>`
same if I try to clone input
variable (with implementing Clone
trait on AIManagerInput
struct).
Could somebody help me to refactor the code so I can define input
variable only once ?
I want to implement something like this:
fn handle_ai(
&mut self,
mut output_sender: Sender<Vec<u8>>,
mut message_income: MessageIncome
) -> JoinHandle<()> {
let session = Arc::clone(&self.session);
let data_storage = Arc::clone(&self.data_storage);
let mut movement_ai = MovementAI::new();
let mut fighting_ai = FightingAI::new();
tokio::spawn(async move {
loop {
let input = AIManagerInput {
session: Arc::clone(&session),
data_storage: Arc::clone(&data_storage),
output_sender: output_sender.clone(),
message_income: message_income.clone(),
};
movement_ai.manage(input.clone()).await;
fighting_ai.manage(input.clone()).await;
}
})
}