Everytime you use await
you give the IC the chance to execute code in another round.
OK. But it looks like the internal counter (limiter) is not limited to one round. I haven’t been able to prove it for sure, but it looks like it is.
Not entirely true. Your canister is called regularly but there’s no guarantee that its happening every round.
Yes. I also realized that
system func heartbeat()
Stops responding if there is a long call. I thought it was a parallel function, since it is marked as a system function
Below I tried to divide a long operation between rounds. For a simple example, counted the factorial of a number. (Although the goal is to calculate sha-2)
system func heartbeat(): async(){
var time = Time.now();
_time_round := _time_round + (time - _time);
if(_time_round > _round){//new round
_time_round := 0;
_count_round := _count_round + 1;
};
_time := time;
};
The actor is executed in parallel on multiple nodes (consensus) Therefore (most likely) any calling function is blocking.
That is, when calculating the factorial (for example), I will not be able to track the rounds.
If you try to track (departures) and restart the operation. Then the call is reset anyway. Below I tried to address the caller from the called canister. But when it hits the catch block, the operation is interrupted.
Below is part of the code
public func calc(_c: Nat, _j: Nat, _d: Nat, callback: shared (Nat, Nat, Nat)-> async ()): async (){
try{
//**We are counting something**//
if(j == d ){
return;
};
await callback(c, j, d);
}
catch e{
ignore await callback(c, j, d); //this line of code is not called
Debug.print("calc error : " # debug_show(Error.message(e)));
}
};