Need to avoid code duplication

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;
		}
	})
}

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.