packages/core/lib/middleware/sampling/rule_cache.js (69 lines of code) (raw):

var TTL = 60 * 60; // The cache expires 1 hour after the last refresh time. /** * The rule cache that stores sampling rules fetched from X-Ray service. * @module RuleCache */ var RuleCache = { rules: [], lastUpdated: null, /** * Tries to find a valid rule that matches the sample request. * @param {object} sampleRequest - Contains information for rules matching. * @param {number} now - Current epoch in seconds. * @module RuleCache * @function getMatchedRule */ getMatchedRule: function getMatchedRule(sampleRequest, now) { if (isExpired(now)) { return null; } var matchedRule; this.rules.forEach(function(rule) { if (!matchedRule && rule.match(sampleRequest)) { matchedRule = rule; } if (rule.isDefault() && !matchedRule) { matchedRule = rule; } }); return matchedRule; }, /** * Load rules fetched from X-Ray service in order sorted by priorities. * @param {object} rules - Newly fetched rules to load. * @module RuleCache * @function loadRules */ loadRules: function loadRules(rules) { // Record the old rules for later merging. var oldRules = {}; this.rules.forEach(function(rule) { oldRules[rule.getName()] = rule; }); // Update the rules in the cache. this.rules = rules; // Transfer state information to refreshed rules. this.rules.forEach(function(rule) { var oldRule = oldRules[rule.getName()]; if (oldRule) { rule.merge(oldRule); } }); // The cache should maintain the order of the rules based on // priority. If priority is the same we sort name by alphabet // as rule name is unique. this.rules.sort(function(a, b) { var v = a.getPriority() - b.getPriority(); if (v !== 0) { return v; } if (a.getName() > b.getName()) { return 1; } else { return -1; } }); }, /** * Load targets fetched from X-Ray service. * @param {object} targetsMapping - Newly fetched targets map with rule name as key. * @module RuleCache * @function loadTargets */ loadTargets: function loadTargets(targetsMapping) { this.rules.forEach(function(rule) { var target = targetsMapping[rule.getName()]; if (target) { rule.getReservoir().loadNewQuota(target.quota, target.TTL, target.interval); rule.setRate(target.rate); } }); }, getRules: function getRules() { return this.rules; }, timestamp: function timestamp(now) { this.lastUpdated = now; }, getLastUpdated: function getLastUpdated() { return this.lastUpdated; } }; var isExpired = function isExpired(now) { // The cache is considered expired if it is never loaded. if (!RuleCache.getLastUpdated()) { return true; } return now > RuleCache.getLastUpdated() + TTL; }; module.exports = RuleCache;