async run()

in common/lib/plugins/efm/monitor.ts [117:225]


  async run(): Promise<void> {
    logger.debug(Messages.get("MonitorImpl.startMonitoring", this.hostInfo.host));

    try {
      while (!this.cancelled) {
        try {
          let newMonitorContext: MonitorConnectionContext | undefined;
          let firstAddedNewMonitorContext: MonitorConnectionContext | null = null;
          const currentTimeNano: number = getCurrentTimeNano();
          while ((newMonitorContext = this.newContexts?.shift()) != null) {
            if (firstAddedNewMonitorContext === newMonitorContext) {
              this.newContexts.push(newMonitorContext);

              break;
            }

            if (newMonitorContext.isActiveContext) {
              if (newMonitorContext.expectedActiveMonitoringStartTimeNano > currentTimeNano) {
                this.newContexts.push(newMonitorContext);

                firstAddedNewMonitorContext = firstAddedNewMonitorContext ?? newMonitorContext;
              } else {
                this.activeContexts.push(newMonitorContext);
              }
            }
          }

          if (this.activeContexts.length > 0) {
            this.contextLastUsedTimestampNanos = getCurrentTimeNano();

            const statusCheckStartTimeNanos: number = getCurrentTimeNano();
            this.contextLastUsedTimestampNanos = statusCheckStartTimeNanos;

            const status: ConnectionStatus = await this.checkConnectionStatus();
            let delayMillis: number = -1;

            let monitorContext: MonitorConnectionContext | undefined;
            let firstAddedMonitorContext: MonitorConnectionContext | null = null;

            while ((monitorContext = this.activeContexts?.shift()) != null) {
              // If context is already invalid, just skip it.
              if (!monitorContext.isActiveContext) {
                continue;
              }

              if (firstAddedMonitorContext == monitorContext) {
                // This context is already processed by this loop.
                // Add it to the array and exit this loop.

                this.activeContexts?.push(monitorContext);
                break;
              }

              // Otherwise, process this context.
              await monitorContext.updateConnectionStatus(
                this.hostInfo.url,
                statusCheckStartTimeNanos,
                statusCheckStartTimeNanos + status.elapsedTimeNano,
                status.isValid
              );

              if (monitorContext.isActiveContext && !monitorContext.isHostUnhealthy) {
                this.activeContexts?.push(monitorContext);

                if (firstAddedMonitorContext == null) {
                  firstAddedMonitorContext = monitorContext;
                }

                if (delayMillis === -1 || delayMillis > monitorContext.failureDetectionIntervalMillis) {
                  delayMillis = monitorContext.failureDetectionIntervalMillis;
                }
              }
            }

            if (delayMillis === -1) {
              // No active contexts.
              delayMillis = this.SLEEP_WHEN_INACTIVE_MILLIS;
            } else {
              delayMillis -= Math.round(status.elapsedTimeNano / 1_000_000);
              // Check for minimum delay between host health check;
              if (delayMillis <= 0) {
                delayMillis = this.MIN_CONNECTION_CHECK_TIMEOUT_MILLIS;
              }
            }

            await new Promise((resolve) => {
              this.delayMillisTimeoutId = setTimeout(resolve, delayMillis);
            });
          } else {
            if (getCurrentTimeNano() - this.contextLastUsedTimestampNanos >= this.monitorDisposalTimeMillis * 1_000_000) {
              break;
            }
            await new Promise((resolve) => {
              this.sleepWhenInactiveTimeoutId = setTimeout(resolve, this.SLEEP_WHEN_INACTIVE_MILLIS);
            });
          }
        } catch (error: any) {
          logger.debug(Messages.get("MonitorImpl.errorDuringMonitoringContinue", error.message));
        }
      }
    } catch (error: any) {
      logger.debug(Messages.get("MonitorImpl.errorDuringMonitoringStop", error.message));
    } finally {
      this.stopped = true;
      await this.endMonitoringClient();
    }

    logger.debug(Messages.get("MonitorImpl.stopMonitoring", this.hostInfo.host));
  }