FWIW, here’s how I calculate load. I don’t know if this is 100% correct, but it does appear to work.
The trick here, is that ru_stime
and ru_utime
are monotonically increasing, and are represented in milliseconds. Therefore, we just need to take slices of time, and compute the load over that slice of time.
async scheduleResourceUsage (timeout) {
this.updateResourceUsage()
this.timeout = setTimeout(() => this.scheduleResourceUsage(timeout), timeout)
}
async updateResourceUsage () {
const { workerLoads, log } = this
let updatedCPULoad = false
for (const worker of this.workers) {
const usage = await worker.getResourceUsage()
const wall = Date.now()
const { ru_stime: systemTime, ru_utime: userTime } = usage
const total = systemTime + userTime
const last = workerLoads.get(worker)
let load
let elapsed
if (last) {
const { wall: lastWall, total: lastTotal } = last
elapsed = wall - lastWall
const usage = total - lastTotal
load = Number((usage / (elapsed * 1.0)).toFixed(3))
updatedCPULoad = true
}
const result = { wall, systemTime, userTime, total, load, elapsed }
log.silly(`Computed worker-${worker.pid} CPU usage`, result)
workerLoads.set(worker, result)
}
if (updatedCPULoad) {
return this.emit('updated-resource-usage')
}
}