前言

HeartBeat(心跳),原本是Rust SDK独有的功能(虽然有些问题),但就在近日,Motoko也悄咪咪地支持了HeartBeat,可以让canister按一定的频率自主执行一些代码或向外发出信号,就像有生命的心脏在跳动……

正文

Internet Computer canisters可以选择通过暴露一个特定的canister_heartbeat函数(参见HeartBeat)来接收常规心跳信息。

对于定期执行或基于时间的执行,WebAssembly 模块可以导出一个函数,该函数的名称为 cansnect_heartbeat。心跳调度算法是实现定义的。
canister_heartbeat 由 IC 触发,因此没有参数,没有调用者,无法回复或拒绝。

在 Motoko 中,actor可以通过声明一个名为 heartbeatsystem函数(没有参数)来接收 heartbeat 消息,并返回unit类型(async ())的future。

一个简单的例子是一个周期性的警报功能,它每第 n 次心跳就向自己发送一条信息:

import Debug "mo:base/Debug";

actor Alarm {

  let n = 5;
  var count = 0;

  public shared func ring() : async () {
    Debug.print("Ring!");
  };

  system func heartbeat() : async () {
    if (count % n == 0) {
      await ring();
    };
    count += 1;
  }
}

当声明 heartbeat 函数时,通过调度对 heartbeat 函数的异步调用,在每个 Internet Computer 子网心跳上调用 heartbeat 函数。由于其async返回类型,heartbeat 函数可能会发送进一步的消息并等待结果。心跳调用的结果(包括任何trap或抛出的error)将被忽略。调用每个 Motoko 异步函数所固有的隐式上下文切换意味着执行Heartbeat主体的时间可能晚于子网发出心跳的时间。

作为一个async函数,Alarm 的Heartbeat函数可以自由调用其他async函数(例如上面的内部调用ring()) ,也可以调用其他canister的shared函数。

TechnicalLibrary1-c014fca5c6227b4230d4f6fb5ce6a44c-1024x563.png

A Student on the way to full stack of Web3.