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;
}