Install prettier and eslint
This commit is contained in:
+88
-78
@@ -9,95 +9,105 @@
|
||||
// adjust the period between gc()'s to reach a target of the gc saving
|
||||
// 4 megabytes each time.
|
||||
|
||||
let MemoryMonitor;
|
||||
const oneMinute = 60 * 1000;
|
||||
const oneMegaByte = 1024 * 1024;
|
||||
let MemoryMonitor
|
||||
const oneMinute = 60 * 1000
|
||||
const oneMegaByte = 1024 * 1024
|
||||
|
||||
let CpuTimeBucket = 100; // current cpu time allowance in milliseconds
|
||||
const CpuTimeBucketMax = 100; // maximum amount of cpu time allowed in bucket
|
||||
const CpuTimeBucketRate = 10; // add this many milliseconds per minute
|
||||
let CpuTimeBucket = 100 // current cpu time allowance in milliseconds
|
||||
const CpuTimeBucketMax = 100 // maximum amount of cpu time allowed in bucket
|
||||
const CpuTimeBucketRate = 10 // add this many milliseconds per minute
|
||||
|
||||
let gcInterval = 1; // how many minutes between gc (parameter is dynamically adjusted)
|
||||
let countSinceLastGc = 0; // how many minutes since last gc
|
||||
const MemoryChunkSize = 4; // how many megabytes we need to free to consider gc worth doing
|
||||
let gcInterval = 1 // how many minutes between gc (parameter is dynamically adjusted)
|
||||
let countSinceLastGc = 0 // how many minutes since last gc
|
||||
const MemoryChunkSize = 4 // how many megabytes we need to free to consider gc worth doing
|
||||
|
||||
const readyToGc = function() {
|
||||
// update allowed cpu time
|
||||
CpuTimeBucket = CpuTimeBucket + CpuTimeBucketRate;
|
||||
CpuTimeBucket = CpuTimeBucket < CpuTimeBucketMax ? CpuTimeBucket : CpuTimeBucketMax;
|
||||
// update counts since last gc
|
||||
countSinceLastGc = countSinceLastGc + 1;
|
||||
// check there is enough time since last gc and we have enough cpu
|
||||
return (countSinceLastGc > gcInterval) && (CpuTimeBucket > 0);
|
||||
};
|
||||
// update allowed cpu time
|
||||
CpuTimeBucket = CpuTimeBucket + CpuTimeBucketRate
|
||||
CpuTimeBucket =
|
||||
CpuTimeBucket < CpuTimeBucketMax ? CpuTimeBucket : CpuTimeBucketMax
|
||||
// update counts since last gc
|
||||
countSinceLastGc = countSinceLastGc + 1
|
||||
// check there is enough time since last gc and we have enough cpu
|
||||
return countSinceLastGc > gcInterval && CpuTimeBucket > 0
|
||||
}
|
||||
|
||||
const executeAndTime = function(fn) {
|
||||
// time the execution of fn() and subtract from cpu allowance
|
||||
const t0 = process.hrtime();
|
||||
fn();
|
||||
const dt = process.hrtime(t0);
|
||||
const timeTaken = (dt[0] + (dt[1]*1e-9)) * 1e3; // in milliseconds
|
||||
CpuTimeBucket -= Math.ceil(timeTaken);
|
||||
return timeTaken;
|
||||
};
|
||||
// time the execution of fn() and subtract from cpu allowance
|
||||
const t0 = process.hrtime()
|
||||
fn()
|
||||
const dt = process.hrtime(t0)
|
||||
const timeTaken = (dt[0] + dt[1] * 1e-9) * 1e3 // in milliseconds
|
||||
CpuTimeBucket -= Math.ceil(timeTaken)
|
||||
return timeTaken
|
||||
}
|
||||
|
||||
const inMegaBytes = function(obj) {
|
||||
// convert process.memoryUsage hash {rss,heapTotal,heapFreed} into megabytes
|
||||
const result = {};
|
||||
for (let k in obj) {
|
||||
const v = obj[k];
|
||||
result[k] = (v / oneMegaByte).toFixed(2);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
// convert process.memoryUsage hash {rss,heapTotal,heapFreed} into megabytes
|
||||
const result = {}
|
||||
for (const k in obj) {
|
||||
const v = obj[k]
|
||||
result[k] = (v / oneMegaByte).toFixed(2)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
const updateMemoryStats = function(oldMem, newMem) {
|
||||
countSinceLastGc = 0;
|
||||
const delta = {};
|
||||
for (let k in newMem) {
|
||||
delta[k] = (newMem[k] - oldMem[k]).toFixed(2);
|
||||
}
|
||||
// take the max of all memory measures
|
||||
const savedMemory = Math.max(-delta.rss, -delta.heapTotal, -delta.heapUsed);
|
||||
delta.megabytesFreed = savedMemory;
|
||||
// did it do any good?
|
||||
if (savedMemory < MemoryChunkSize) {
|
||||
gcInterval = gcInterval + 1; // no, so wait longer next time
|
||||
} else {
|
||||
gcInterval = Math.max(gcInterval - 1, 1); // yes, wait less time
|
||||
}
|
||||
return delta;
|
||||
};
|
||||
countSinceLastGc = 0
|
||||
const delta = {}
|
||||
for (const k in newMem) {
|
||||
delta[k] = (newMem[k] - oldMem[k]).toFixed(2)
|
||||
}
|
||||
// take the max of all memory measures
|
||||
const savedMemory = Math.max(-delta.rss, -delta.heapTotal, -delta.heapUsed)
|
||||
delta.megabytesFreed = savedMemory
|
||||
// did it do any good?
|
||||
if (savedMemory < MemoryChunkSize) {
|
||||
gcInterval = gcInterval + 1 // no, so wait longer next time
|
||||
} else {
|
||||
gcInterval = Math.max(gcInterval - 1, 1) // yes, wait less time
|
||||
}
|
||||
return delta
|
||||
}
|
||||
|
||||
module.exports = (MemoryMonitor = {
|
||||
monitor(logger) {
|
||||
const interval = setInterval(() => MemoryMonitor.Check(logger)
|
||||
, oneMinute);
|
||||
const Metrics = require("./index");
|
||||
return Metrics.registerDestructor(() => clearInterval(interval));
|
||||
},
|
||||
module.exports = MemoryMonitor = {
|
||||
monitor(logger) {
|
||||
const interval = setInterval(() => MemoryMonitor.Check(logger), oneMinute)
|
||||
const Metrics = require('./index')
|
||||
return Metrics.registerDestructor(() => clearInterval(interval))
|
||||
},
|
||||
|
||||
Check(logger) {
|
||||
let mem;
|
||||
const Metrics = require("./index");
|
||||
const memBeforeGc = (mem = inMegaBytes(process.memoryUsage()));
|
||||
Metrics.gauge("memory.rss", mem.rss);
|
||||
Metrics.gauge("memory.heaptotal", mem.heapTotal);
|
||||
Metrics.gauge("memory.heapused", mem.heapUsed);
|
||||
Metrics.gauge("memory.gc-interval", gcInterval);
|
||||
//Metrics.gauge("memory.cpu-time-bucket", CpuTimeBucket)
|
||||
Check(logger) {
|
||||
let mem
|
||||
const Metrics = require('./index')
|
||||
const memBeforeGc = (mem = inMegaBytes(process.memoryUsage()))
|
||||
Metrics.gauge('memory.rss', mem.rss)
|
||||
Metrics.gauge('memory.heaptotal', mem.heapTotal)
|
||||
Metrics.gauge('memory.heapused', mem.heapUsed)
|
||||
Metrics.gauge('memory.gc-interval', gcInterval)
|
||||
// Metrics.gauge("memory.cpu-time-bucket", CpuTimeBucket)
|
||||
|
||||
logger.log(mem, "process.memoryUsage()");
|
||||
logger.log(mem, 'process.memoryUsage()')
|
||||
|
||||
if ((global.gc != null) && readyToGc()) {
|
||||
const gcTime = (executeAndTime(global.gc)).toFixed(2);
|
||||
const memAfterGc = inMegaBytes(process.memoryUsage());
|
||||
const deltaMem = updateMemoryStats(memBeforeGc, memAfterGc);
|
||||
logger.log({gcTime, memBeforeGc, memAfterGc, deltaMem, gcInterval, CpuTimeBucket}, "global.gc() forced");
|
||||
//Metrics.timing("memory.gc-time", gcTime)
|
||||
Metrics.gauge("memory.gc-rss-freed", -deltaMem.rss);
|
||||
Metrics.gauge("memory.gc-heaptotal-freed", -deltaMem.heapTotal);
|
||||
return Metrics.gauge("memory.gc-heapused-freed", -deltaMem.heapUsed);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (global.gc != null && readyToGc()) {
|
||||
const gcTime = executeAndTime(global.gc).toFixed(2)
|
||||
const memAfterGc = inMegaBytes(process.memoryUsage())
|
||||
const deltaMem = updateMemoryStats(memBeforeGc, memAfterGc)
|
||||
logger.log(
|
||||
{
|
||||
gcTime,
|
||||
memBeforeGc,
|
||||
memAfterGc,
|
||||
deltaMem,
|
||||
gcInterval,
|
||||
CpuTimeBucket
|
||||
},
|
||||
'global.gc() forced'
|
||||
)
|
||||
// Metrics.timing("memory.gc-time", gcTime)
|
||||
Metrics.gauge('memory.gc-rss-freed', -deltaMem.rss)
|
||||
Metrics.gauge('memory.gc-heaptotal-freed', -deltaMem.heapTotal)
|
||||
return Metrics.gauge('memory.gc-heapused-freed', -deltaMem.heapUsed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user