under-pressure
Advanced tools
Comparing version 5.5.0 to 5.6.0
import { | ||
FastifyPlugin | ||
FastifyPlugin, | ||
FastifyReply, | ||
FastifyRequest | ||
} from "fastify"; | ||
export const TYPE_EVENT_LOOP_DELAY = 'eventLoopDelay' | ||
export const TYPE_HEAP_USED_BYTES = 'heapUsedBytes' | ||
export const TYPE_RSS_BYTES = 'rssBytes' | ||
export const TYPE_HEALTH_CHECK = 'healthCheck' | ||
export const TYPE_EVENT_LOOP_UTILIZATION = 'eventLoopUtilization' | ||
declare namespace underPressure { | ||
@@ -15,2 +23,3 @@ interface UnderPressureOptions { | ||
healthCheckInterval?: number; | ||
pressureHandler?: (request: FastifyRequest, reply: FastifyReply, type: string, value: number | undefined) => Promise<void> | void; | ||
sampleInterval?: number; | ||
@@ -17,0 +26,0 @@ exposeStatusRoute?: boolean | string | { routeOpts: object; routeSchemaOpts?: object; routeResponseSchemaOpts?: object; url?: string }; |
40
index.js
@@ -12,2 +12,8 @@ 'use strict' | ||
const TYPE_EVENT_LOOP_DELAY = 'eventLoopDelay' | ||
const TYPE_HEAP_USED_BYTES = 'heapUsedBytes' | ||
const TYPE_RSS_BYTES = 'rssBytes' | ||
const TYPE_HEALTH_CHECK = 'healthCheck' | ||
const TYPE_EVENT_LOOP_UTILIZATION = 'eventLoopUtilization' | ||
function getSampleInterval (value, eventLoopResolution) { | ||
@@ -31,2 +37,3 @@ const defaultValue = monitorEventLoopDelay ? 1000 : 5 | ||
const maxEventLoopUtilization = opts.maxEventLoopUtilization || 0 | ||
const pressureHandler = opts.pressureHandler | ||
@@ -161,3 +168,3 @@ const checkMaxEventLoopDelay = maxEventLoopDelay > 0 | ||
if (checkMaxEventLoopDelay && eventLoopDelay > maxEventLoopDelay) { | ||
sendError(reply, next) | ||
handlePressure(req, reply, next, TYPE_EVENT_LOOP_DELAY, eventLoopDelay) | ||
return | ||
@@ -167,3 +174,3 @@ } | ||
if (checkMaxHeapUsedBytes && heapUsed > maxHeapUsedBytes) { | ||
sendError(reply, next) | ||
handlePressure(req, reply, next, TYPE_HEAP_USED_BYTES, heapUsed) | ||
return | ||
@@ -173,3 +180,3 @@ } | ||
if (checkMaxRssBytes && rssBytes > maxRssBytes) { | ||
sendError(reply, next) | ||
handlePressure(req, reply, next, TYPE_RSS_BYTES, rssBytes) | ||
return | ||
@@ -179,3 +186,3 @@ } | ||
if (!externalsHealthy) { | ||
sendError(reply, next) | ||
handlePressure(req, reply, next, TYPE_HEALTH_CHECK) | ||
return | ||
@@ -185,3 +192,3 @@ } | ||
if (checkMaxEventLoopUtilization && eventLoopUtilized > maxEventLoopUtilization) { | ||
sendError(reply, next) | ||
handlePressure(req, reply, next, TYPE_EVENT_LOOP_UTILIZATION, eventLoopUtilized) | ||
return | ||
@@ -193,5 +200,16 @@ } | ||
function sendError (reply, next) { | ||
reply.status(SERVICE_UNAVAILABLE).header('Retry-After', retryAfter) | ||
next(underPressureError) | ||
function handlePressure (req, reply, next, type, value) { | ||
if (typeof pressureHandler === 'function') { | ||
const result = pressureHandler(req, reply, type, value) | ||
if (result instanceof Promise) { | ||
result.then(() => next(), next) | ||
} else if (result == null) { | ||
next() | ||
} else { | ||
reply.send(result) | ||
} | ||
} else { | ||
reply.status(SERVICE_UNAVAILABLE).header('Retry-After', retryAfter) | ||
next(underPressureError) | ||
} | ||
} | ||
@@ -246,1 +264,7 @@ | ||
}) | ||
module.exports.TYPE_EVENT_LOOP_DELAY = TYPE_EVENT_LOOP_DELAY | ||
module.exports.TYPE_EVENT_LOOP_UTILIZATION = TYPE_EVENT_LOOP_UTILIZATION | ||
module.exports.TYPE_HEALTH_CHECK = TYPE_HEALTH_CHECK | ||
module.exports.TYPE_HEAP_USED_BYTES = TYPE_HEAP_USED_BYTES | ||
module.exports.TYPE_RSS_BYTES = TYPE_RSS_BYTES |
{ | ||
"name": "under-pressure", | ||
"version": "5.5.0", | ||
"version": "5.6.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", | ||
"unit": "tap -j 1 test/*test.js", | ||
"test": "npm run lint && npm run unit && npm run typescript", | ||
@@ -11,0 +11,0 @@ "typescript": "tsd" |
@@ -83,2 +83,38 @@ # under-pressure | ||
#### Pressure Handler | ||
You can provide a pressure handler in the options to handle the pressure errors. The advantage is that you know for which reason the error occured. And the request can be handled as if nothing happened. | ||
```js | ||
const fastify = require('fastify')() | ||
const underPressure = require('under-pressure')() | ||
fastify.register(underPressure, { | ||
maxHeapUsedBytes: 100000000, | ||
maxRssBytes: 100000000, | ||
pressureHandler: (req, rep, type, value) => { | ||
if (type === underPressure.TYPE_HEAP_USED_BYTES) { | ||
fastify.log.warn(`too many heap bytes used: ${value}`) | ||
} else if (type === underPressure.TYPE_RSS_BYTES) { | ||
fastify.log.warn(`too many rss bytes used: ${value}`) | ||
} | ||
rep.send('out of memory') // if you omit this line, the request will be handled normally | ||
} | ||
}) | ||
``` | ||
It is possible as well to return a Promise which will call `reply.send` (or something else). | ||
```js | ||
fastify.register(underPressure, { | ||
maxHeapUsedBytes: 100000000, | ||
pressureHandler: (req, rep, type, value) => { | ||
return getPromise().then(() => reply.send({hello: 'world'})) | ||
} | ||
}) | ||
``` | ||
Any other return value than a promise or nullish will be sent to client with `reply.send`. | ||
#### Status route | ||
@@ -85,0 +121,0 @@ If needed you can pass `{ exposeStatusRoute: true }` and `under-pressure` will expose a `/status` route for you that sends back a `{ status: 'ok' }` object. This can be useful if you need to attach the server to an ELB on AWS for example. |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
46654
14
1197
213
5
1