under-pressure
Advanced tools
Comparing version 3.2.1 to 4.0.0
36
index.js
@@ -5,7 +5,15 @@ 'use strict' | ||
const assert = require('assert') | ||
const { monitorEventLoopDelay } = require('perf_hooks') | ||
function getSampleInterval (value, eventLoopResolution) { | ||
const defaultValue = monitorEventLoopDelay ? 1000 : 5 | ||
const sampleInterval = value || defaultValue | ||
return monitorEventLoopDelay ? Math.max(eventLoopResolution, sampleInterval) : sampleInterval | ||
} | ||
async function underPressure (fastify, opts) { | ||
opts = opts || {} | ||
const sampleInterval = opts.sampleInterval || 5 | ||
const resolution = 10 | ||
const sampleInterval = getSampleInterval(opts.sampleInterval, resolution) | ||
const maxEventLoopDelay = opts.maxEventLoopDelay || 0 | ||
@@ -24,3 +32,12 @@ const maxHeapUsedBytes = opts.maxHeapUsedBytes || 0 | ||
var eventLoopDelay = 0 | ||
var lastCheck = now() | ||
var lastCheck | ||
var histogram | ||
if (monitorEventLoopDelay) { | ||
histogram = monitorEventLoopDelay({ resolution }) | ||
histogram.enable() | ||
} else { | ||
lastCheck = now() | ||
} | ||
const timer = setInterval(updateMemoryUsage, sampleInterval) | ||
@@ -100,2 +117,13 @@ timer.unref() | ||
function updateEventLoopDelay () { | ||
if (histogram) { | ||
eventLoopDelay = Math.max(0, histogram.mean / 1e6 - resolution) | ||
histogram.reset() | ||
} else { | ||
const toCheck = now() | ||
eventLoopDelay = Math.max(0, toCheck - lastCheck - sampleInterval) | ||
lastCheck = toCheck | ||
} | ||
} | ||
function updateMemoryUsage () { | ||
@@ -105,5 +133,3 @@ var mem = process.memoryUsage() | ||
rssBytes = mem.rss | ||
var toCheck = now() | ||
eventLoopDelay = toCheck - lastCheck - sampleInterval | ||
lastCheck = toCheck | ||
updateEventLoopDelay() | ||
} | ||
@@ -110,0 +136,0 @@ |
{ | ||
"name": "under-pressure", | ||
"version": "3.2.1", | ||
"version": "4.0.0", | ||
"description": "Measure process load with automatic handling of 'Service Unavailable' plugin for Fastify.", | ||
@@ -8,3 +8,3 @@ "main": "index.js", | ||
"lint": "standard | snazzy", | ||
"unit": "tap test.js --no-coverage", | ||
"unit": "tap test.js", | ||
"test": "npm run lint && npm run unit && npm run typescript", | ||
@@ -30,9 +30,9 @@ "typescript": "tsc --project ./tsconfig.json" | ||
"dependencies": { | ||
"fastify-plugin": "^1.5.0" | ||
"fastify-plugin": "^1.6.1" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^12.7.3", | ||
"fastify": "^2.3.0", | ||
"fastify": "^2.13.1", | ||
"pre-commit": "^1.2.2", | ||
"simple-get": "^3.0.3", | ||
"simple-get": "^3.1.0", | ||
"snazzy": "^8.0.0", | ||
@@ -44,4 +44,4 @@ "standard": "^14.0.0", | ||
"engines": { | ||
"node": ">=8" | ||
"node": ">=10" | ||
} | ||
} |
# under-pressure | ||
[![Greenkeeper badge](https://badges.greenkeeper.io/fastify/under-pressure.svg)](https://greenkeeper.io/) | ||
[![Build Status](https://img.shields.io/github/workflow/status/fastify/under-pressure/CI)](https://github.com/fastify/under-pressure/actions) | ||
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](http://standardjs.com/) | ||
[![Build Status](https://travis-ci.org/fastify/under-pressure.svg?branch=master)](https://travis-ci.org/fastify/under-pressure) | ||
@@ -111,3 +110,19 @@ Measure process load with automatic handling of *"Service Unavailable"* plugin for Fastify. | ||
``` | ||
<a name="sample-interval"></a> | ||
#### Sample interval | ||
You can set a custom value for sampling the metrics returned by `memoryUsage` using the `sampleInterval` option, which accepts a number that represents the interval in milliseconds. | ||
The default value is different depending on which Node version is used. On version 8 and 10 it is `5`, while on version 11.10.0 and up it is `1000`. This difference is due to the fact that from version 11.10.0 the event loop delay can be sampled with [`monitorEventLoopDelay`](https://nodejs.org/docs/latest-v12.x/api/perf_hooks.html#perf_hooks_perf_hooks_monitoreventloopdelay_options) and this allows to increase the interval value. | ||
```js | ||
const fastify = require('fastify')() | ||
fastify.register(require('under-pressure'), { | ||
sampleInterval: <your custom sample interval in ms> | ||
}) | ||
``` | ||
<a name="acknowledgements"></a> | ||
@@ -114,0 +129,0 @@ ## Acknowledgements |
62
test.js
@@ -5,6 +5,10 @@ 'use strict' | ||
const test = t.test | ||
const { promisify } = require('util') | ||
const sget = require('simple-get').concat | ||
const Fastify = require('fastify') | ||
const { monitorEventLoopDelay } = require('perf_hooks') | ||
const underPressure = require('./index') | ||
const wait = promisify(setTimeout) | ||
test('Should return 503 on maxEventLoopDelay', t => { | ||
@@ -15,3 +19,3 @@ t.plan(5) | ||
fastify.register(underPressure, { | ||
maxEventLoopDelay: 50 | ||
maxEventLoopDelay: 15 | ||
}) | ||
@@ -23,8 +27,15 @@ | ||
fastify.listen(0, (err, address) => { | ||
fastify.listen(0, async (err, address) => { | ||
t.error(err) | ||
fastify.server.unref() | ||
// If using monitorEventLoopDelay give it time to collect | ||
// some samples | ||
if (monitorEventLoopDelay) { | ||
await wait(500) | ||
} | ||
// Increased to prevent Travis to fail | ||
process.nextTick(() => sleep(1000)) | ||
process.nextTick(() => block(1000)) | ||
sget({ | ||
@@ -63,3 +74,4 @@ method: 'GET', | ||
process.nextTick(() => sleep(500)) | ||
process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) | ||
sget({ | ||
@@ -97,3 +109,5 @@ method: 'GET', | ||
fastify.server.unref() | ||
process.nextTick(() => sleep(500)) | ||
process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) | ||
sget({ | ||
@@ -121,3 +135,3 @@ method: 'GET', | ||
fastify.register(underPressure, { | ||
maxEventLoopDelay: 50, | ||
maxRssBytes: 1, | ||
message: 'Under pressure!', | ||
@@ -135,3 +149,4 @@ retryAfter: 50 | ||
process.nextTick(() => sleep(500)) | ||
process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) | ||
sget({ | ||
@@ -171,3 +186,3 @@ method: 'GET', | ||
fastify.listen(0, (err, address) => { | ||
fastify.listen(0, async (err, address) => { | ||
t.error(err) | ||
@@ -177,3 +192,10 @@ t.is(typeof fastify.memoryUsage, 'function') | ||
process.nextTick(() => sleep(500)) | ||
// If using monitorEventLoopDelay give it time to collect | ||
// some samples | ||
if (monitorEventLoopDelay) { | ||
await wait(500) | ||
} | ||
process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) | ||
sget({ | ||
@@ -204,3 +226,3 @@ method: 'GET', | ||
fastify.listen(0, (err, address) => { | ||
fastify.listen(0, async (err, address) => { | ||
t.error(err) | ||
@@ -210,3 +232,10 @@ t.is(typeof fastify.memoryUsage, 'function') | ||
process.nextTick(() => sleep(500)) | ||
// If using monitorEventLoopDelay give it time to collect | ||
// some samples | ||
if (monitorEventLoopDelay) { | ||
await wait(500) | ||
} | ||
process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) | ||
sget({ | ||
@@ -236,3 +265,4 @@ method: 'GET', | ||
process.nextTick(() => sleep(500)) | ||
process.nextTick(() => block(monitorEventLoopDelay ? 1500 : 500)) | ||
sget({ | ||
@@ -295,3 +325,3 @@ method: 'GET', | ||
fastify.server.unref() | ||
process.nextTick(() => sleep(500)) | ||
process.nextTick(() => block(500)) | ||
t.strictEqual(routeOptions.url, '/alive') | ||
@@ -319,3 +349,3 @@ t.strictEqual(routeOptions.logLevel, 'silent', 'log level not set') | ||
fastify.server.unref() | ||
process.nextTick(() => sleep(500)) | ||
process.nextTick(() => block(500)) | ||
t.strictEqual(routeOptions.url, '/status') | ||
@@ -455,3 +485,3 @@ t.strictEqual(routeOptions.logLevel, 'silent', 'log level not set') | ||
healthCheck: async () => { | ||
await new Promise(resolve => setTimeout(() => resolve(), 100)) | ||
await wait(100) | ||
t.false(called) | ||
@@ -544,5 +574,5 @@ called = true | ||
function sleep (msec) { | ||
function block (msec) { | ||
const start = Date.now() | ||
while (Date.now() - start < msec) {} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
28695
12
751
136
2
Updatedfastify-plugin@^1.6.1