pub struct Call<'m, 'a> { /* private fields */ }Expand description
Inter-canister Call.
This type enables the configuration and execution of inter-canister calls using a builder pattern.
§Constructors
Call has two constructors that differentiate whether the call’s response is waited for an unbounded amount of time or not.
bounded_wait: wait boundedly (defaults with 300-second timeout).unbounded_wait: wait unboundedly.
§Configuration
Before execution, a Call can be configured in following aspects:
- Arguments:
with_arg: singleCandidTypevalue that will be encoded.with_args: a tuple of multipleCandidTypevalues that will be encoded.with_raw_args: raw bytes that won’t be encoded.- Note: If no methods in this category are invoked, the
Calldefaults to sending a Candid empty tuple().
- Cycles:
with_cycles: set the cycles attached in this call.
- Response waiting timeout:
change_timeout: change the timeout forbounded_waitcall.
Please note that all the configuration methods are chainable and can be called multiple times. For each aspect of the call, the last configuration takes effect.
§Example
let call = Call::bounded_wait(canister_id, method)
.with_raw_args(&[1,0])
.with_cycles(1000)
.change_timeout(5)
.with_arg(42)
.with_cycles(2000);The call above will have the following configuration in effect:
- Arguments:
42encoded as Candid bytes. - Attach 2000 cycles.
- Boundedly waiting for response with a 5-second timeout.
§Execution
A Call can be executed in two ways:
- Asynchronously: Convert to a
CallFutureand await the response.- Direct approach: Use
.awaiton the call (e.g.,call.await). - Collective approach: Use
IntoFuture::into_futureto obtain futures explicitly, then combine them withjoin!,select!, or other combinators.
- Direct approach: Use
- One-way: Send a call with
onewaywhen you don’t need a response.
§Example
let response = Call::bounded_wait(canister_id, method).await;
let calls = vec![
Call::bounded_wait(canister_id1, method1).into_future(),
Call::bounded_wait(canister_id2, method2).into_future(),
];
let responses = futures::future::join_all(calls).await;
Call::bounded_wait(canister_id, method).oneway().unwrap();§Decoding the response
If an asynchronous Call succeeds, the response can be decoded in two ways:
candid: decode the response as a single Candid type.candid_tuple: decode the response as a tuple of Candid types.
§Example
let res: Response = Call::bounded_wait(canister_id, method).await.unwrap();
let result: u32 = res.candid().unwrap();
let result_tuple: (u32,) = res.candid_tuple().unwrap();Using an inter-canister call creates the possibility that your async function will be canceled partway through.
Read the futures module docs for why and how this happens.
Implementations§
Source§impl<'m> Call<'m, '_>
impl<'m> Call<'m, '_>
Sourcepub fn bounded_wait(canister_id: Principal, method: &'m str) -> Call<'m, '_>
pub fn bounded_wait(canister_id: Principal, method: &'m str) -> Call<'m, '_>
Constructs a Call which will boundedly wait for response.
§Note
The bounded waiting is set with a default 300-second timeout.
It aligns with the MAX_CALL_TIMEOUT constant in the current IC implementation.
The timeout can be changed using the change_timeout method.
To unboundedly wait for response, use the Call::unbounded_wait constructor instead.
Sourcepub fn unbounded_wait(canister_id: Principal, method: &'m str) -> Call<'m, '_>
pub fn unbounded_wait(canister_id: Principal, method: &'m str) -> Call<'m, '_>
Constructs a Call which will unboundedly wait for response.
To boundedly wait for response, use the Call::bounded_wait constructor instead.
Source§impl<'a> Call<'_, 'a>
impl<'a> Call<'_, 'a>
Sourcepub fn with_arg<A>(self, arg: A) -> Call<'_, 'a>where
A: CandidType,
pub fn with_arg<A>(self, arg: A) -> Call<'_, 'a>where
A: CandidType,
Sets the argument for the call.
The argument must implement CandidType.
Sourcepub fn with_args<A>(self, args: &A) -> Call<'_, 'a>where
A: ArgumentEncoder,
pub fn with_args<A>(self, args: &A) -> Call<'_, 'a>where
A: ArgumentEncoder,
Sets the arguments for the call.
The arguments are a tuple of types, each implementing CandidType.
Sourcepub fn with_raw_args(self, raw_args: &'a [u8]) -> Call<'_, 'a>
pub fn with_raw_args(self, raw_args: &'a [u8]) -> Call<'_, 'a>
Sets the arguments for the call as raw bytes.
§Note
This method just borrows the bytes, so it is useful when making multiple calls with the same argument data.
The Call object will be tied to the lifetime of the argument bytes,
which may prevent storing the call in collections or returning it from functions
if the arguments don’t live long enough.
For cases where you need to transfer ownership of the arguments bytes consider using Self::take_raw_args instead.
Sourcepub fn take_raw_args(self, raw_args: Vec<u8>) -> Call<'_, 'a>
pub fn take_raw_args(self, raw_args: Vec<u8>) -> Call<'_, 'a>
Sets the arguments for the call as raw bytes and consumes the bytes.
§Note
This method takes ownership of the arguments bytes, so it is useful
when you want to store the call in collections or return a Call from functions.
For cases where you want to make multiple calls with the same argument data,
consider using Self::with_raw_args instead to avoid unnecessary cloning.
Sourcepub fn with_cycles(self, cycles: u128) -> Call<'_, 'a>
pub fn with_cycles(self, cycles: u128) -> Call<'_, 'a>
Sets the cycles payment for the call.
§Note
The behavior of this method when invoked multiple times is as follows:
- Overrides any previously set cycle value
- Last invocation determines the final cycles amount
- Does not accumulate cycles across multiple invocations
Sourcepub fn change_timeout(self, timeout_seconds: u32) -> Call<'_, 'a>
pub fn change_timeout(self, timeout_seconds: u32) -> Call<'_, 'a>
Changes the timeout for bounded response waiting.
If invoked multiple times, the last value takes effect.
The timeout value is silently capped by the MAX_CALL_TIMEOUT constant which is currently set to 300 seconds.
Therefore, setting a timeout greater than 300 seconds will actually result in a 300-second timeout.
§Panics
This method will panic if invoked on an unbounded response waiting call constructed by Call::unbounded_wait .
§Note
A timeout of 0 second DOES NOT mean unbounded response waiting.
The call would most likely time out (result in a SysUnknown reject).
Unless it’s a call to the canister on the same subnet,
and the execution manages to schedule both the request and the response in the same round.
To unboundedly wait for response, use the Call::unbounded_wait constructor instead.
Sourcepub fn get_cost(&self) -> u128
pub fn get_cost(&self) -> u128
Returns the amount of cycles a canister needs to be above the freezing threshold in order to
successfully perform this call. Takes into account the attached cycles (with_cycles)
as well as
- the method name byte length
- the payload length
- the cost of transmitting the request
- the cost for the reservation of response transmission (may be partially refunded)
- the cost for the reservation of callback execution (may be partially refunded).