I'm trying to use the Arc<T>
type to share a reference to a data structure that connects me to a remote service (Amazon S3 object storage). I want to configure the connection once, and then share an immutable reference with several Futures, across one or more threads.
I thought that using an Arc<T>
would allow me to pass the Arc
immutable reference into the async
function and share it across separate Future
instances. However, I am required to call the clone()
method on the Arc
for it to work correctly. How is this any different / better than simply cloning the S3 Client struct for each Future
?
First, I define an async
function that creates some random objects in a bucket, accepting an Arc<Client>
parameter.
async fn create_object(s3_client: Arc<Client>, bucket_name: String) {
....
}
In the main
function, I create my S3 client, using the AWS SDK. And then wrap it in Arc<T>
let s3_client = s3::Client::new(&aws_cfg); // This is an aws_sdk_s3::Client struct
// https://docs.rs/aws-sdk-s3/latest/aws_sdk_s3/struct.Client.html
let s3_client_arc = Arc::new(s3_client);
Then I create a couple of threads:
let mut join_handle_list = vec![]; // Holds the JoinHandle instances from spawn()
for _ in 1..=2 {
let new_future = create_object(s3_client_arc, bucket_name.clone());
join_handle_list.push(tokio::spawn(new_future));
}
However, this results in the common error message:
use of moved value:
s3_client_arc
; value moved here, in previous iteration of loop
The work-around seems to be to call .clone()
on the Arc<T>
, but this seems to defeat the purpose of using the Arc<T>
to wrap the Client
, right?
This compiles successfully:
let mut join_handle_list = vec![]; // Holds the JoinHandle instances from spawn()
for _ in 1..=2 {
let new_future = create_object(s3_client_arc.clone(), bucket_name.clone());
join_handle_list.push(tokio::spawn(new_future));
}
What's the correct way to do this? The first example in the documentation seems to indicate that the correct way is to use clone()
, but it feels like this is inefficient. Is this more efficient than simply calling .clone()
on the Client
struct itself, without using Arc<T>
?