private TriggerFireResult fire(String triggerName, Tablet tablet, TriggerEvent event) {
    TriggerFireResult result = TriggerFireResult.SUCCESS;
    for (int i = 0; i < FIRE_RETRY_NUM; i++) {
      if (TriggerManagementService.getInstance().needToFireOnAnotherDataNode(triggerName)) {
        TDataNodeLocation tDataNodeLocation =
            TriggerManagementService.getInstance()
                .getDataNodeLocationOfStatefulTrigger(triggerName);
        try (SyncDataNodeInternalServiceClient client =
            Coordinator.getInstance()
                .getInternalServiceClientManager()
                .borrowClient(tDataNodeLocation.getInternalEndPoint())) {
          TFireTriggerReq req = new TFireTriggerReq(triggerName, tablet.serialize(), event.getId());
          TFireTriggerResp resp = client.fireTrigger(req);
          if (resp.foundExecutor) {
            // we successfully found an executor on another data node
            return TriggerFireResult.construct(resp.getFireResult());
          } else {
            // update TDataNodeLocation of stateful trigger through config node
            if (!updateLocationOfStatefulTrigger(triggerName, tDataNodeLocation.getDataNodeId())) {
              // if TDataNodeLocation is still the same, sleep 1s and before the retry
              Thread.sleep(4000);
            }
          }
        } catch (ClientManagerException | TException e) {
          // IOException means that we failed to borrow client, possibly because corresponding
          // DataNode is down.
          // TException means there's a timeout or broken connection.
          // We need to update local TriggerTable with the new TDataNodeLocation of the stateful
          // trigger.
          LOGGER.warn(
              "Error occurred when trying to fire trigger({}) on TEndPoint: {}, the cause is: {}",
              triggerName,
              tDataNodeLocation.getInternalEndPoint(),
              e);
          // update TDataNodeLocation of stateful trigger through config node
          updateLocationOfStatefulTrigger(triggerName, tDataNodeLocation.getDataNodeId());
        } catch (InterruptedException e) {
          LOGGER.warn("{} interrupted when sleep", triggerName);
          Thread.currentThread().interrupt();
        } catch (Exception e) {
          LOGGER.warn(
              "Error occurred when trying to fire trigger({}) on TEndPoint: {}, the cause is: {}",
              triggerName,
              tDataNodeLocation.getInternalEndPoint(),
              e);
          // do not retry if it is not due to bad network or no executor found
          return TriggerManagementService.getInstance()
                  .getTriggerInformation(triggerName)
                  .getFailureStrategy()
                  .equals(FailureStrategy.OPTIMISTIC)
              ? TriggerFireResult.FAILED_NO_TERMINATION
              : TriggerFireResult.TERMINATION;
        }
      } else {
        TriggerExecutor executor = TriggerManagementService.getInstance().getExecutor(triggerName);
        if (executor == null) {
          return TriggerManagementService.getInstance()
                  .getTriggerInformation(triggerName)
                  .getFailureStrategy()
                  .equals(FailureStrategy.PESSIMISTIC)
              ? TriggerFireResult.TERMINATION
              : TriggerFireResult.FAILED_NO_TERMINATION;
        }
        try {
          boolean fireResult = executor.fire(tablet, event);
          if (!fireResult) {
            result =
                executor.getFailureStrategy().equals(FailureStrategy.PESSIMISTIC)
                    ? TriggerFireResult.TERMINATION
                    : TriggerFireResult.FAILED_NO_TERMINATION;
          }
        } catch (TriggerExecutionException e) {
          result =
              executor.getFailureStrategy().equals(FailureStrategy.PESSIMISTIC)
                  ? TriggerFireResult.TERMINATION
                  : TriggerFireResult.FAILED_NO_TERMINATION;
        }
        return result;
      }
    }
    return result;
  }
How many times should we retry when error occurred during firing a trigger on another datanode.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/trigger/executor/TriggerFireVisitor.java