async function getEngineAnalysis()

in src/scaler/scaler-core/scaling-methods/base.js [124:200]


async function getEngineAnalysis(cluster, ruleSet) {
  if (!ruleSet) return null;

  logger.debug({
    message:
      `---- ${cluster.projectId}/${cluster.regionId}/${cluster.clusterId}: ` +
      `${cluster.scalingMethod} rules engine ----`,
    projectId: cluster.projectId,
    regionId: cluster.regionId,
    clusterId: cluster.clusterId,
  });

  const rulesEngine = new Engine();

  Object.values(ruleSet).forEach((rule) => {
    rulesEngine.addRule(rule);
  });

  const /** @type {!RuleEngineAnalysis} */ engineAnalysis = {
      firingRuleCount: {
        [AutoscalerDirection.IN]: 0,
        [AutoscalerDirection.OUT]: 0,
      },
      matchedConditions: {
        [AutoscalerDirection.IN]: [],
        [AutoscalerDirection.OUT]: [],
      },
      scalingMetrics: {
        [AutoscalerDirection.IN]: new Set(),
        [AutoscalerDirection.OUT]: new Set(),
      },
    };

  rulesEngine.on('success', function (event, _, ruleResult) {
    logger.debug({
      message: `\tRule firing: ${event.params?.message} => ${event.type}`,
      projectId: cluster.projectId,
      regionId: cluster.regionId,
      clusterId: cluster.clusterId,
      event: event,
    });

    const ruleConditions = getRuleConditionMetrics(ruleResult);
    const /** @type {!Set<string>} */ scalingMetrics =
        event.params?.scalingMetrics || new Set();
    if (
      event.type === AutoscalerDirection.OUT ||
      event.type === AutoscalerDirection.IN
    ) {
      engineAnalysis.firingRuleCount[event.type]++;
      engineAnalysis.matchedConditions[event.type].push(
        ...Object.values(ruleConditions),
      );
      for (const scalingMetric of scalingMetrics) {
        engineAnalysis.scalingMetrics[event.type].add(scalingMetric);
      }
    } else {
      logger.debug({
        message: `\tIgnoring unexpectedly firing rule of type ${event.type}`,
        projectId: cluster.projectId,
        regionId: cluster.regionId,
        clusterId: cluster.clusterId,
        event: event,
      });
    }
  });

  const facts = {};
  Object.values(cluster.metrics).forEach((metric) => {
    // @ts-ignore
    facts[metric.name] = metric.value; // TODO strict types
  });

  await rulesEngine.run(facts);

  return engineAnalysis;
}