diff --git a/README.md b/README.md index b4a0b1d..77c5509 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ external resources. ## Requirements -Fastify ^2.0.0. Please refer to [this branch](https://github.com/fastify/under-pressure/tree/1.x) and related versions for Fastify ^1.1.0 compatibility. +Fastify ^4.0.0. Please refer to [this branch](https://github.com/fastify/under-pressure/tree/1.x) and related versions for Fastify ^1.1.0 compatibility. ## Install @@ -35,6 +35,9 @@ fastify.register(require('@fastify/under-pressure'), { }) fastify.get('/', (req, reply) => { + if (fastify.isUnderPressure()) { + // skip complex computation + } reply.send({ hello: 'world'}) }) diff --git a/index.js b/index.js index 6d29b8c..30d7475 100644 --- a/index.js +++ b/index.js @@ -60,6 +60,7 @@ async function fastifyUnderPressure (fastify, opts) { } fastify.decorate('memoryUsage', memoryUsage) + fastify.decorate('isUnderPressure', isUnderPressure) const timer = setTimeout(beginMemoryUsageUpdate, sampleInterval) timer.unref() @@ -173,6 +174,30 @@ async function fastifyUnderPressure (fastify, opts) { updateEventLoopUtilization() } + function isUnderPressure () { + if (checkMaxEventLoopDelay && eventLoopDelay > maxEventLoopDelay) { + return true + } + + if (checkMaxHeapUsedBytes && heapUsed > maxHeapUsedBytes) { + return true + } + + if (checkMaxRssBytes && rssBytes > maxRssBytes) { + return true + } + + if (!externalsHealthy) { + return true + } + + if (checkMaxEventLoopUtilization && eventLoopUtilized > maxEventLoopUtilization) { + return true + } + + return false + } + function onRequest (req, reply, next) { if (checkMaxEventLoopDelay && eventLoopDelay > maxEventLoopDelay) { handlePressure(req, reply, next, TYPE_EVENT_LOOP_DELAY, eventLoopDelay) diff --git a/test/test.js b/test/test.js index b1d1261..b4afd33 100644 --- a/test/test.js +++ b/test/test.js @@ -11,7 +11,7 @@ const { valid, satisfies, coerce } = require('semver') const wait = promisify(setTimeout) test('Should return 503 on maxEventLoopDelay', t => { - t.plan(5) + t.plan(6) const fastify = Fastify() fastify.register(underPressure, { @@ -42,6 +42,7 @@ test('Should return 503 on maxEventLoopDelay', t => { message: 'Service Unavailable', statusCode: 503 }) + t.equal(fastify.isUnderPressure(), true) fastify.close() }) @@ -51,7 +52,7 @@ test('Should return 503 on maxEventLoopDelay', t => { const isSupportedVersion = satisfies(valid(coerce(process.version)), '12.19.0 || >=14.0.0') test('Should return 503 on maxEventloopUtilization', { skip: !isSupportedVersion }, t => { - t.plan(5) + t.plan(6) const fastify = Fastify() fastify.register(underPressure, { maxEventLoopUtilization: 0.60 @@ -75,6 +76,7 @@ test('Should return 503 on maxEventloopUtilization', { skip: !isSupportedVersion message: 'Service Unavailable', statusCode: 503 }) + t.equal(fastify.isUnderPressure(), true) fastify.close() }) @@ -83,7 +85,7 @@ test('Should return 503 on maxEventloopUtilization', { skip: !isSupportedVersion }) test('Should return 503 on maxHeapUsedBytes', t => { - t.plan(5) + t.plan(6) const fastify = Fastify() fastify.register(underPressure, { @@ -108,6 +110,7 @@ test('Should return 503 on maxHeapUsedBytes', t => { message: 'Service Unavailable', statusCode: 503 }) + t.equal(fastify.isUnderPressure(), true) fastify.close() }) @@ -116,7 +119,7 @@ test('Should return 503 on maxHeapUsedBytes', t => { }) test('Should return 503 on maxRssBytes', t => { - t.plan(5) + t.plan(6) const fastify = Fastify() fastify.register(underPressure, { @@ -141,6 +144,7 @@ test('Should return 503 on maxRssBytes', t => { message: 'Service Unavailable', statusCode: 503 }) + t.equal(fastify.isUnderPressure(), true) fastify.close() }) @@ -231,7 +235,7 @@ test('Custom error instance', t => { }) test('memoryUsage name space', t => { - t.plan(9) + t.plan(10) const fastify = Fastify() fastify.register(underPressure, { @@ -264,6 +268,7 @@ test('memoryUsage name space', t => { t.error(err) t.equal(response.statusCode, 200) t.same(JSON.parse(body), { hello: 'world' }) + t.equal(fastify.isUnderPressure(), true) fastify.close() }) @@ -311,7 +316,7 @@ test('Custom health check', t => { t.plan(8) t.test('should return 503 when custom health check returns false for healthCheck', t => { - t.plan(5) + t.plan(6) const fastify = Fastify() fastify.register(underPressure, { @@ -339,6 +344,7 @@ test('Custom health check', t => { message: 'Service Unavailable', statusCode: 503 }) + t.equal(fastify.isUnderPressure(), true) fastify.close() }) }) diff --git a/types/index.d.ts b/types/index.d.ts index 9c374ef..f7e767f 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -8,6 +8,7 @@ import { declare module "fastify" { interface FastifyInstance { memoryUsage(): { heapUsed: number; rssBytes: number; eventLoopDelay: number; eventLoopUtilized: number }; + isUnderPressure(): boolean; } } diff --git a/types/index.test-d.ts b/types/index.test-d.ts index 0b2ac8c..08d35fb 100644 --- a/types/index.test-d.ts +++ b/types/index.test-d.ts @@ -14,7 +14,8 @@ const server = fastify(); server.register(fastifyUnderPressure); server.get("/", (req, reply) => { - reply.send({ hello: "world" }); + + reply.send({ hello: "world", underPressure: server.isUnderPressure() }); }); server.listen({port: 3000}, err => {