UNPKG

faastjs

Version:

Serverless batch computing made simple.

118 lines 13.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MemoryLeakDetector = exports.FunctionCpuUsage = exports.FunctionStatsMap = exports.FactoryMap = void 0; const provider_1 = require("./provider"); const shared_1 = require("./shared"); class FactoryMap extends Map { constructor(factory) { super(); this.factory = factory; } getOrCreate(key) { let val = this.get(key); if (!val) { val = this.factory(key); this.set(key, val); } return val; } } exports.FactoryMap = FactoryMap; class FunctionStatsMap { constructor() { this.fIncremental = new FactoryMap(() => new provider_1.FunctionStats()); this.fAggregate = new FactoryMap(() => new provider_1.FunctionStats()); this.aggregate = new provider_1.FunctionStats(); } update(fn, key, value) { this.fIncremental.getOrCreate(fn)[key].update(value); this.fAggregate.getOrCreate(fn)[key].update(value); this.aggregate[key].update(value); } incr(fn, key, n = 1) { this.fIncremental.getOrCreate(fn)[key] += n; this.fAggregate.getOrCreate(fn)[key] += n; this.aggregate[key] += n; } resetIncremental() { this.fIncremental.clear(); } toString() { return [...this.fAggregate].map(([key, value]) => `[${key}] ${value}`).join("\n"); } clear() { this.fIncremental.clear(); this.fAggregate.clear(); } } exports.FunctionStatsMap = FunctionStatsMap; class FunctionCpuUsage { constructor() { this.utime = new shared_1.Statistics(); this.stime = new shared_1.Statistics(); this.cpuTime = new shared_1.Statistics(); this.smallest = new shared_1.SmallestN(100); } } exports.FunctionCpuUsage = FunctionCpuUsage; class FunctionMemoryStats { constructor() { this.rss = new shared_1.Statistics(); this.heapTotal = new shared_1.Statistics(); this.heapUsed = new shared_1.Statistics(); this.external = new shared_1.Statistics(); } } class FunctionMemoryCounters { constructor() { this.heapUsedGrowth = 0; this.externalGrowth = 0; } } class MemoryLeakDetector { constructor(memorySize) { this.instances = new FactoryMap(() => new FunctionMemoryStats()); this.counters = new FactoryMap(() => new FunctionMemoryCounters()); this.warned = new Set(); this.memorySize = memorySize || 100; } detectedNewLeak(fn, instanceId, memoryUsage) { if (this.warned.has(fn)) { return false; } const { rss, heapTotal, heapUsed, external } = memoryUsage; const instanceStats = this.instances.getOrCreate(instanceId); const counters = this.counters.getOrCreate(instanceId); if (heapUsed > instanceStats.heapUsed.max) { counters.heapUsedGrowth++; } else { counters.heapUsedGrowth = 0; } if (external > instanceStats.external.max) { counters.externalGrowth++; } else { counters.externalGrowth = 0; } instanceStats.rss.update(rss); instanceStats.heapTotal.update(heapTotal); instanceStats.heapUsed.update(heapUsed); instanceStats.external.update(external); if (heapUsed > this.memorySize * 0.8 * 2 ** 20 || external > this.memorySize * 0.8 * 2 ** 20) { if (counters.heapUsedGrowth > 4 || counters.externalGrowth > 4) { this.warned.add(fn); return true; } } return false; } clear() { this.instances.clear(); this.counters.clear(); this.warned.clear(); } } exports.MemoryLeakDetector = MemoryLeakDetector; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0cmljcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tZXRyaWNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHlDQUEyQztBQUMzQyxxQ0FBaUQ7QUFHakQsTUFBYSxVQUErQixTQUFRLEdBQVM7SUFDekQsWUFBcUIsT0FBc0I7UUFDdkMsS0FBSyxFQUFFLENBQUM7UUFEUyxZQUFPLEdBQVAsT0FBTyxDQUFlO0lBRTNDLENBQUM7SUFFRCxXQUFXLENBQUMsR0FBTTtRQUNkLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDeEIsSUFBSSxDQUFDLEdBQUcsRUFBRTtZQUNOLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3hCLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1NBQ3RCO1FBQ0QsT0FBTyxHQUFHLENBQUM7SUFDZixDQUFDO0NBQ0o7QUFiRCxnQ0FhQztBQUVELE1BQWEsZ0JBQWdCO0lBQTdCO1FBQ0ksaUJBQVksR0FBRyxJQUFJLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLHdCQUFhLEVBQUUsQ0FBQyxDQUFDO1FBQ3pELGVBQVUsR0FBRyxJQUFJLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLHdCQUFhLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZELGNBQVMsR0FBRyxJQUFJLHdCQUFhLEVBQUUsQ0FBQztJQThCcEMsQ0FBQztJQTVCRyxNQUFNLENBQ0YsRUFBVSxFQUNWLEdBQXNELEVBQ3RELEtBQWE7UUFFYixJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDckQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFD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QixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3hCLENBQUM7Q0FDSjtBQWpERCxnREFpREMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBGdW5jdGlvblN0YXRzIH0gZnJvbSBcIi4vcHJvdmlkZXJcIjtcbmltcG9ydCB7IFNtYWxsZXN0TiwgU3RhdGlzdGljcyB9IGZyb20gXCIuL3NoYXJlZFwiO1xuaW1wb3J0IHsgUHJvcGVydGllc09mVHlwZSB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbmV4cG9ydCBjbGFzcyBGYWN0b3J5TWFwPEsgPSBzdHJpbmcsIFYgPSB7fT4gZXh0ZW5kcyBNYXA8SywgVj4ge1xuICAgIGNvbnN0cnVjdG9yKHJlYWRvbmx5IGZhY3Rvcnk6IChrZXk6IEspID0+IFYpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICBnZXRPckNyZWF0ZShrZXk6IEspIHtcbiAgICAgICAgbGV0IHZhbCA9IHRoaXMuZ2V0KGtleSk7XG4gICAgICAgIGlmICghdmFsKSB7XG4gICAgICAgICAgICB2YWwgPSB0aGlzLmZhY3Rvcnkoa2V5KTtcbiAgICAgICAgICAgIHRoaXMuc2V0KGtleSwgdmFsKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIEZ1bmN0aW9uU3RhdHNNYXAge1xuICAgIGZJbmNyZW1lbnRhbCA9IG5ldyBGYWN0b3J5TWFwKCgpID0+IG5ldyBGdW5jdGlvblN0YXRzKCkpO1xuICAgIGZBZ2dyZWdhdGUgPSBuZXcgRmFjdG9yeU1hcCgoKSA9PiBuZXcgRnVuY3Rpb25TdGF0cygpKTtcbiAgICBhZ2dyZWdhdGUgPSBuZXcgRnVuY3Rpb25TdGF0cygpO1xuXG4gICAgdXBkYXRlKFxuICAgICAgICBmbjogc3RyaW5nLFxuICAgICAgICBrZXk6IGtleW9mIFByb3BlcnRpZXNPZlR5cGU8RnVuY3Rpb25TdGF0cywgU3RhdGlzdGljcz4sXG4gICAgICAgIHZhbHVlOiBudW1iZXJcbiAgICApIHtcbiAgICAgICAgdGhpcy5mSW5jcmVtZW50YWwuZ2V0T3JDcmVhdGUoZm4pW2tleV0udXBkYXRlKHZhbHVlKTtcbiAgICAgICAgdGhpcy5mQWdncmVnYXRlLmdldE9yQ3JlYXRlKGZuKVtrZXldLnVwZGF0ZSh2YWx1ZSk7XG4gICAgICAgIHRoaXMuYWdncmVnYXRlW2tleV0udXBkYXRlKHZhbHVlKTtcbiAgICB9XG5cbiAgICBpbmNyKGZuOiBzdHJpbmcsIGtleToga2V5b2YgUHJvcGVydGllc09mVHlwZTxGdW5jdGlvblN0YXRzLCBudW1iZXI+LCBuOiBudW1iZXIgPSAxKSB7XG4gICAgICAgIHRoaXMuZkluY3JlbWVudGFsLmdldE9yQ3JlYXRlKGZuKVtrZXldICs9IG47XG4gICAgICAgIHRoaXMuZkFnZ3JlZ2F0ZS5nZXRPckNyZWF0ZShmbilba2V5XSArPSBuO1xuICAgICAgICB0aGlzLmFnZ3JlZ2F0ZVtrZXldICs9IG47XG4gICAgfVxuXG4gICAgcmVzZXRJbmNyZW1lbnRhbCgpIHtcbiAgICAgICAgdGhpcy5mSW5jcmVtZW50YWwuY2xlYXIoKTtcbiAgICB9XG5cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgcmV0dXJuIFsuLi50aGlzLmZBZ2dyZWdhdGVdLm1hcCgoW2tleSwgdmFsdWVdKSA9PiBgWyR7a2V5fV0gJHt2YWx1ZX1gKS5qb2luKFwiXFxuXCIpO1xuICAgIH1cblxuICAgIGNsZWFyKCkge1xuICAgICAgICB0aGlzLmZJbmNyZW1lbnRhbC5jbGVhcigpO1xuICAgICAgICB0aGlzLmZBZ2dyZWdhdGUuY2xlYXIoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBGdW5jdGlvbkNwdVVzYWdlIHtcbiAgICB1dGltZSA9IG5ldyBTdGF0aXN0aWNzKCk7XG4gICAgc3RpbWUgPSBuZXcgU3RhdGlzdGljcygpO1xuICAgIGNwdVRpbWUgPSBuZXcgU3RhdGlzdGljcygpO1xuICAgIHNtYWxsZXN0ID0gbmV3IFNtYWxsZXN0TigxMDApO1xufVxuXG5jbGFzcyBGdW5jdGlvbk1lbW9yeVN0YXRzIHtcbiAgICByc3MgPSBuZXcgU3RhdGlzdGljcygpO1xuICAgIGhlYXBUb3RhbCA9IG5ldyBTdGF0aXN0aWNzKCk7XG4gICAgaGVhcFVzZWQgPSBuZXcgU3RhdGlzdGljcygpO1xuICAgIGV4dGVybmFsID0gbmV3IFN0YXRpc3RpY3MoKTtcbn1cblxuY2xhc3MgRnVuY3Rpb25NZW1vcnlDb3VudGVycyB7XG4gICAgaGVhcFVzZWRHcm93dGggPSAwO1xuICAgIGV4dGVybmFsR3Jvd3RoID0gMDtcbn1cblxuZXhwb3J0IGNsYXNzIE1lbW9yeUxlYWtEZXRlY3RvciB7XG4gICAgcHJpdmF0ZSBpbnN0YW5jZXMgPSBuZXcgRmFjdG9yeU1hcCgoKSA9PiBuZXcgRnVuY3Rpb25NZW1vcnlTdGF0cygpKTtcbiAgICBwcml2YXRlIGNvdW50ZXJzID0gbmV3IEZhY3RvcnlNYXAoKCkgPT4gbmV3IEZ1bmN0aW9uTWVtb3J5Q291bnRlcnMoKSk7XG4gICAgcHJpdmF0ZSB3YXJuZWQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBwcml2YXRlIG1lbW9yeVNpemU6IG51bWJlcjtcblxuICAgIGNvbnN0cnVjdG9yKG1lbW9yeVNpemU/OiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy5tZW1vcnlTaXplID0gbWVtb3J5U2l6ZSB8fCAxMDA7XG4gICAgfVxuXG4gICAgZGV0ZWN0ZWROZXdMZWFrKGZuOiBzdHJpbmcsIGluc3RhbmNlSWQ6IHN0cmluZywgbWVtb3J5VXNhZ2U6IE5vZGVKUy5NZW1vcnlVc2FnZSkge1xuICAgICAgICBpZiAodGhpcy53YXJuZWQuaGFzKGZuKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHsgcnNzLCBoZWFwVG90YWwsIGhlYXBVc2VkLCBleHRlcm5hbCB9ID0gbWVtb3J5VXNhZ2U7XG4gICAgICAgIGNvbnN0IGluc3RhbmNlU3RhdHMgPSB0aGlzLmluc3RhbmNlcy5nZXRPckNyZWF0ZShpbnN0YW5jZUlkKTtcbiAgICAgICAgY29uc3QgY291bnRlcnMgPSB0aGlzLmNvdW50ZXJzLmdldE9yQ3JlYXRlKGluc3RhbmNlSWQpO1xuICAgICAgICBpZiAoaGVhcFVzZWQgPiBpbnN0YW5jZVN0YXRzLmhlYXBVc2VkLm1heCkge1xuICAgICAgICAgICAgY291bnRlcnMuaGVhcFVzZWRHcm93dGgrKztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvdW50ZXJzLmhlYXBVc2VkR3Jvd3RoID0gMDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXh0ZXJuYWwgPiBpbnN0YW5jZVN0YXRzLmV4dGVybmFsLm1heCkge1xuICAgICAgICAgICAgY291bnRlcnMuZXh0ZXJuYWxHcm93dGgrKztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvdW50ZXJzLmV4dGVybmFsR3Jvd3RoID0gMDtcbiAgICAgICAgfVxuICAgICAgICBpbnN0YW5jZVN0YXRzLnJzcy51cGRhdGUocnNzKTtcbiAgICAgICAgaW5zdGFuY2VTdGF0cy5oZWFwVG90YWwudXBkYXRlKGhlYXBUb3RhbCk7XG4gICAgICAgIGluc3RhbmNlU3RhdHMuaGVhcFVzZWQudXBkYXRlKGhlYXBVc2VkKTtcbiAgICAgICAgaW5zdGFuY2VTdGF0cy5leHRlcm5hbC51cGRhdGUoZXh0ZXJuYWwpO1xuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIGhlYXBVc2VkID4gdGhpcy5tZW1vcnlTaXplICogMC44ICogMiAqKiAyMCB8fFxuICAgICAgICAgICAgZXh0ZXJuYWwgPiB0aGlzLm1lbW9yeVNpemUgKiAwLjggKiAyICoqIDIwXG4gICAgICAgICkge1xuICAgICAgICAgICAgaWYgKGNvdW50ZXJzLmhlYXBVc2VkR3Jvd3RoID4gNCB8fCBjb3VudGVycy5leHRlcm5hbEdyb3d0aCA+IDQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLndhcm5lZC5hZGQoZm4pO1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjbGVhcigpIHtcbiAgICAgICAgdGhpcy5pbnN0YW5jZXMuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5jb3VudGVycy5jbGVhcigpO1xuICAgICAgICB0aGlzLndhcm5lZC5jbGVhcigpO1xuICAgIH1cbn1cbiJdfQ==