code: func (d *Dispatcher) Heartbeat(ctx context.Context, r *api.HeartbeatRequest) (*api.HeartbeatResponse, error) {
  	d.rpcRW.RLock()
  	defer d.rpcRW.RUnlock()
  
  	// TODO(anshul) Explore if its possible to check context here without locking.
  	if _, err := d.isRunningLocked(); err != nil {
  		return nil, status.Errorf(codes.Aborted, "dispatcher is stopped")
  	}
  
  	nodeInfo, err := ca.RemoteNode(ctx)
  	if err != nil {
  		return nil, err
  	}
  
  	period, err := d.nodes.Heartbeat(nodeInfo.NodeID, r.SessionID)
  
  	log.G(ctx).WithField("method", "(*Dispatcher).Heartbeat").Debugf("received heartbeat from worker %v, expect next heartbeat in %v", nodeInfo, period)
  	return &api.HeartbeatResponse{Period: period}, err
  }
docs: // Heartbeat is heartbeat method for nodes. It returns new TTL in response.
  // Node should send new heartbeat earlier than now + TTL, otherwise it will
  // be deregistered from dispatcher and its status will be updated to NodeStatus_DOWN