Are message responses guaranteed on the IC?

From reading this thread, it seems there will be a change that allows developers to choose between Best-Effort Messages and Small Messages with Guaranteed Responses.

That post also mentions:

The long term goal of messaging on the IC is to ensure that canisters can rely on canister-to-canister messaging, irrespective of subnet load and with reasonable operational costs.
This goal is impossible to achieve with the current messaging model;

So does that mean, in practice, something like this is possible:

try {
  let #ok(reponse) = await canisterB.getMyResponse() else return
  savedResponses := response // Never called because #ok or #err was never sent back
} catch (error) {
 // error never caught
}

If canister B executes some code successfully and tries sending the #ok response back, but canister A never gets it, thats when things get very tricky as a developer to handle, because if you call it a second time you might get an error like “response already sent” and you will never know what the result of that was.

Does anyone have any knowledge, experiences or thoughts on this?

Tagging a couple of people: @infu @skilesare @icme

1 Like

This has not been released yet. When it is, the pattern to follow is to produce a unique request ID that can be sent along with a second request. The other canister can then cancel it if it has already processed that request ID.

1 Like

What about in the current system? Can a response never be received or an error caught, under specific circumstances?

The current system guarantees a response to the point that if you call a malicious canister and they decide to just hold on to the request, you can’t restart your canister because it will wait for the response. You can timeout if your request stays in the outgoing queue for too long(5minutes I think) but once it is gone you are going to get a response or die trying.

1 Like

So there is also a scenario where lets say canister B executed some code successfully and tried sending the response back - but maybe it’s lagging and it hit a timeout in it’s outgoing queue.

So canister A, never got anything in this scenario?

Well…in that scenario it wouldn’t be a response. If you send a request out you cannon shut down your canister until you are delivered a response. If b is delayed you just kind of chill until b is ready to respond. You can process other requests, but you can’t start/stop your canister.

Do you know if the response can be timed out in B’s outgoing queue then? Meaning this can happen:

I don’t think so. B has a response queue and I haven’t heard anything about responses being timed out…only outgoing requests.