RUST: How do you make inter-canister calls from within a thread-local variable's closure?

When you store data with the thread_local way of storing things, how do you make an intercanister call from within the closure?

I have code that looks like this:

CANISTER_DATA.with(|canister_data| {
  let data_to_query_with = &canister_data.borrow().data_to_query_with;
  // perform intercanister call that needs to be **awaited**
  // this call uses the above obtained data to make the call
}

How do I make this work? Since closures with parameters are not allowed to be async?

Thoughts?
@roman-kashitsyn @lwshang

1 Like

I’m a Rust noob, so following snippet might be close to garbage but, I guess you can clone the borrowed state:

async fn something() {
   let data_to_query_with = CANISTER_DATA.with(|canister_data| canister_data.borrow().data_to_query_with.clone());

   // use above obtained data
   let _ = your_call(&data_to_query_with).await;
}
1 Like

Thank you. This should work

Is it possible to borrow that value mutably? And then update it based on the response received from the inter canister call?

Or should I just immutably clone it and then reinitialize it and set the value back into the refcell in a subsequent step?

I was struggling to make this work earlier and the documentation here states that

the contained value which cannot be sent across threads or escape the given closure

Hence, I wasn’t completely sure if this was possible at all.

So, the prescribed solution is to basically clone the state and not get a reference to it outside of the closure?

Making calls from thread-local closures is impossible, and it’s a good thing. The compiler prevents you from shooting yourself in the foot. You might find this section of my article on Rust Canisters helpful:

1 Like

Well, I’m a full noob, so what I do might not be what shall be done at all.

But yes, I would go with the second solution. I generally scope mutable values to functions that are close to the state. Like I create a module store.rs in which I take care of all read or update values of the state. Everywhere else I don’t access the state directly and I try generally to avoid mutable values.

But, again, I’m a noob. Only my two cents.

1 Like