Prioritise canister call in queue over other canister

Say canister A calls some other canister B via an update call for endpoint “x” and that canister B is also having more update calls invoked by other canisters for same reason endpoint “x”. These calls will get queued and canister will handle them in order they were invoked from other multiple canisters, right?

If above case is true,

  1. Are there any ways to prioritise your canister A inter canister call to canister B over other canisters?

  2. Are there any ways to prioritise your call to canister B, when you are calling canister B from client using dfinity agent instead of canister A?

1 Like

Likely, but not guaranteed. The interface spec guarantees that calls between two canisters don’t get reordered, but this holds only for every pair of canisters. Given the current implementation I would say you can expect messages to not get reordered (especially if all canisters are on the same subnet). But please don’t bank on it too much.

At the moment there is a lot happening in terms of the new messaging model. Once that is implemented, then I could see some message reordering happen if a canister is under load.

Regarding your concrete questions 1 and 2 the answer to both is No.

1 Like

Calls from a given callee are always processed in the order in which they were made (this is the request ordering guarantee – if I first make a transaction then query the balance, I want the two calls to execute in that order).

Calls across multiple callers are currently executed round-robin. E.g. if you have 3 messages (requests or responses) from canister A – [a1, a2, a3] – and 2 calls from canister B – [b1, b2] – they will be executed in the order [a1, b1, a2, b2, a3]. This is not part of the specification, it is just an implementation choice and may change in the future (e.g. to take into account how many instructions each message execution consumed).

To specifically answer your questions, the system does not at this time provide any means for a canister to prioritize one input over another. But if this is a requirement for you, you could presumably implement the logic yourself inside your canister (or in a proxy canister): instead of directly and immediately handling every request, put them in a priority queue and rely on a timer-based event loop to do the actual processing, in priority order. It will likely require switching to an asynchronous API (similar to ingress messages: issue the call, then poll for the outcome), but it seems doable (although it may be helped by some form of sleep() API).