@tramvai/module-request-limiter 2.47.0 → 2.47.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/lib/requestLimiter.d.ts +10 -1
- package/lib/server.es.js +51 -5
- package/lib/server.js +51 -4
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -41,7 +41,13 @@ const provider = {
|
|
|
41
41
|
|
|
42
42
|
### Configuration
|
|
43
43
|
|
|
44
|
-
You can pass
|
|
44
|
+
You can pass environment variables to configure specific request limiter options:
|
|
45
|
+
|
|
46
|
+
- `REQUEST_LIMITER_MELD` - configure `maxEventLoopDelay` options parameter
|
|
47
|
+
- `REQUEST_LIMITER_QUEUE` - configure `queue` options parameter
|
|
48
|
+
- `REQUEST_LIMITER_LIMIT` - configure `limit` options parameter
|
|
49
|
+
|
|
50
|
+
Another way, you can pass options to request limiter by `REQUESTS_LIMITER_OPTIONS_TOKEN` token (have lowest priority than env variables):
|
|
45
51
|
|
|
46
52
|
```ts
|
|
47
53
|
import { REQUESTS_LIMITER_OPTIONS_TOKEN } from '@tramvai/module-request-limiter';
|
package/lib/requestLimiter.d.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import type { FastifyRequest, FastifyReply, HookHandlerDoneFunction } from 'fastify';
|
|
2
|
+
export declare const DEFAULT_OPTIONS: {
|
|
3
|
+
limit: number;
|
|
4
|
+
queue: number;
|
|
5
|
+
maxEventLoopDelay: number;
|
|
6
|
+
error: {
|
|
7
|
+
httpStatus: number;
|
|
8
|
+
message: string;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
2
11
|
export interface RequestLimiterOptions {
|
|
3
12
|
limit?: number;
|
|
4
13
|
queue?: number;
|
|
@@ -23,7 +32,7 @@ export declare class RequestLimiter {
|
|
|
23
32
|
private minimalActiveRequestLimit;
|
|
24
33
|
private maxEventLoopDelay;
|
|
25
34
|
private eventLoopHistogram;
|
|
26
|
-
constructor(options
|
|
35
|
+
constructor(options: RequestLimiterOptions);
|
|
27
36
|
onResponse(): void;
|
|
28
37
|
private nextTick;
|
|
29
38
|
add(request: RequestLimiterRequest): void;
|
package/lib/server.es.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { __decorate } from 'tslib';
|
|
2
2
|
import { Module, provide, Scope } from '@tramvai/core';
|
|
3
|
+
import { ENV_USED_TOKEN, ENV_MANAGER_TOKEN } from '@tramvai/tokens-common';
|
|
3
4
|
import { WEB_FASTIFY_APP_LIMITER_TOKEN } from '@tramvai/tokens-server-private';
|
|
4
5
|
import fp from 'fastify-plugin';
|
|
5
6
|
import { HttpError } from '@tinkoff/errors';
|
|
@@ -75,11 +76,11 @@ const DEFAULT_OPTIONS = {
|
|
|
75
76
|
};
|
|
76
77
|
const resolution = 10;
|
|
77
78
|
class RequestLimiter {
|
|
78
|
-
constructor(options
|
|
79
|
+
constructor(options) {
|
|
79
80
|
this.currentActive = 0;
|
|
80
81
|
this.eventLoopDelay = 0;
|
|
81
82
|
this.queue = new DoubleLinkedList();
|
|
82
|
-
const { limit
|
|
83
|
+
const { limit, queue, maxEventLoopDelay, error } = options;
|
|
83
84
|
this.activeRequestLimit = limit;
|
|
84
85
|
this.minimalActiveRequestLimit = Math.round(limit / 3);
|
|
85
86
|
this.queueLimit = queue;
|
|
@@ -154,18 +155,63 @@ let RequestLimiterModule = class RequestLimiterModule {
|
|
|
154
155
|
RequestLimiterModule = __decorate([
|
|
155
156
|
Module({
|
|
156
157
|
providers: [
|
|
158
|
+
provide({
|
|
159
|
+
provide: ENV_USED_TOKEN,
|
|
160
|
+
multi: true,
|
|
161
|
+
useValue: [
|
|
162
|
+
{
|
|
163
|
+
key: 'REQUEST_LIMITER_MELD',
|
|
164
|
+
optional: true,
|
|
165
|
+
value: String(DEFAULT_OPTIONS.maxEventLoopDelay),
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
key: 'REQUEST_LIMITER_QUEUE',
|
|
169
|
+
optional: true,
|
|
170
|
+
value: String(DEFAULT_OPTIONS.queue),
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
key: 'REQUEST_LIMITER_LIMIT',
|
|
174
|
+
optional: true,
|
|
175
|
+
value: String(DEFAULT_OPTIONS.limit),
|
|
176
|
+
},
|
|
177
|
+
],
|
|
178
|
+
}),
|
|
179
|
+
provide({
|
|
180
|
+
provide: REQUESTS_LIMITER_OPTIONS_TOKEN,
|
|
181
|
+
useFactory: ({ envManager }) => ({
|
|
182
|
+
maxEventLoopDelay: Number(envManager.get('REQUEST_LIMITER_MELD')),
|
|
183
|
+
queue: Number(envManager.get('REQUEST_LIMITER_QUEUE')),
|
|
184
|
+
limit: Number(envManager.get('REQUEST_LIMITER_LIMIT')),
|
|
185
|
+
}),
|
|
186
|
+
deps: {
|
|
187
|
+
envManager: ENV_MANAGER_TOKEN,
|
|
188
|
+
},
|
|
189
|
+
}),
|
|
157
190
|
provide({
|
|
158
191
|
provide: REQUESTS_LIMITER_TOKEN,
|
|
159
192
|
scope: Scope.SINGLETON,
|
|
160
|
-
useFactory: ({ options, featureEnable }) => {
|
|
193
|
+
useFactory: ({ options, featureEnable, envManager }) => {
|
|
194
|
+
var _a, _b, _c, _d;
|
|
161
195
|
if (featureEnable === false) {
|
|
162
196
|
return;
|
|
163
197
|
}
|
|
164
|
-
|
|
198
|
+
const meld = envManager.get('REQUEST_LIMITER_MELD');
|
|
199
|
+
const queue = envManager.get('REQUEST_LIMITER_QUEUE');
|
|
200
|
+
const limit = envManager.get('REQUEST_LIMITER_LIMIT');
|
|
201
|
+
const resultOptions = {
|
|
202
|
+
limit: limit ? Number(limit) : (_a = options === null || options === void 0 ? void 0 : options.limit) !== null && _a !== void 0 ? _a : DEFAULT_OPTIONS.limit,
|
|
203
|
+
queue: queue ? Number(queue) : (_b = options === null || options === void 0 ? void 0 : options.queue) !== null && _b !== void 0 ? _b : DEFAULT_OPTIONS.queue,
|
|
204
|
+
maxEventLoopDelay: meld
|
|
205
|
+
? Number(meld)
|
|
206
|
+
: (_c = options === null || options === void 0 ? void 0 : options.maxEventLoopDelay) !== null && _c !== void 0 ? _c : DEFAULT_OPTIONS.maxEventLoopDelay,
|
|
207
|
+
error: (_d = options === null || options === void 0 ? void 0 : options.error) !== null && _d !== void 0 ? _d : DEFAULT_OPTIONS.error,
|
|
208
|
+
};
|
|
209
|
+
return new RequestLimiter(resultOptions);
|
|
165
210
|
},
|
|
166
211
|
deps: {
|
|
167
212
|
options: { token: REQUESTS_LIMITER_OPTIONS_TOKEN, optional: true },
|
|
168
213
|
featureEnable: { token: REQUESTS_LIMITER_ACTIVATE_TOKEN, optional: true },
|
|
214
|
+
envManager: ENV_MANAGER_TOKEN,
|
|
169
215
|
},
|
|
170
216
|
}),
|
|
171
217
|
provide({
|
|
@@ -188,4 +234,4 @@ RequestLimiterModule = __decorate([
|
|
|
188
234
|
})
|
|
189
235
|
], RequestLimiterModule);
|
|
190
236
|
|
|
191
|
-
export { REQUESTS_LIMITER_ACTIVATE_TOKEN, REQUESTS_LIMITER_OPTIONS_TOKEN, REQUESTS_LIMITER_TOKEN, RequestLimiter, RequestLimiterModule, fastifyRequestsLimiter };
|
|
237
|
+
export { DEFAULT_OPTIONS, REQUESTS_LIMITER_ACTIVATE_TOKEN, REQUESTS_LIMITER_OPTIONS_TOKEN, REQUESTS_LIMITER_TOKEN, RequestLimiter, RequestLimiterModule, fastifyRequestsLimiter };
|
package/lib/server.js
CHANGED
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var tslib = require('tslib');
|
|
6
6
|
var core = require('@tramvai/core');
|
|
7
|
+
var tokensCommon = require('@tramvai/tokens-common');
|
|
7
8
|
var tokensServerPrivate = require('@tramvai/tokens-server-private');
|
|
8
9
|
var fp = require('fastify-plugin');
|
|
9
10
|
var errors = require('@tinkoff/errors');
|
|
@@ -84,11 +85,11 @@ const DEFAULT_OPTIONS = {
|
|
|
84
85
|
};
|
|
85
86
|
const resolution = 10;
|
|
86
87
|
class RequestLimiter {
|
|
87
|
-
constructor(options
|
|
88
|
+
constructor(options) {
|
|
88
89
|
this.currentActive = 0;
|
|
89
90
|
this.eventLoopDelay = 0;
|
|
90
91
|
this.queue = new DoubleLinkedList();
|
|
91
|
-
const { limit
|
|
92
|
+
const { limit, queue, maxEventLoopDelay, error } = options;
|
|
92
93
|
this.activeRequestLimit = limit;
|
|
93
94
|
this.minimalActiveRequestLimit = Math.round(limit / 3);
|
|
94
95
|
this.queueLimit = queue;
|
|
@@ -163,18 +164,63 @@ exports.RequestLimiterModule = class RequestLimiterModule {
|
|
|
163
164
|
exports.RequestLimiterModule = tslib.__decorate([
|
|
164
165
|
core.Module({
|
|
165
166
|
providers: [
|
|
167
|
+
core.provide({
|
|
168
|
+
provide: tokensCommon.ENV_USED_TOKEN,
|
|
169
|
+
multi: true,
|
|
170
|
+
useValue: [
|
|
171
|
+
{
|
|
172
|
+
key: 'REQUEST_LIMITER_MELD',
|
|
173
|
+
optional: true,
|
|
174
|
+
value: String(DEFAULT_OPTIONS.maxEventLoopDelay),
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
key: 'REQUEST_LIMITER_QUEUE',
|
|
178
|
+
optional: true,
|
|
179
|
+
value: String(DEFAULT_OPTIONS.queue),
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
key: 'REQUEST_LIMITER_LIMIT',
|
|
183
|
+
optional: true,
|
|
184
|
+
value: String(DEFAULT_OPTIONS.limit),
|
|
185
|
+
},
|
|
186
|
+
],
|
|
187
|
+
}),
|
|
188
|
+
core.provide({
|
|
189
|
+
provide: REQUESTS_LIMITER_OPTIONS_TOKEN,
|
|
190
|
+
useFactory: ({ envManager }) => ({
|
|
191
|
+
maxEventLoopDelay: Number(envManager.get('REQUEST_LIMITER_MELD')),
|
|
192
|
+
queue: Number(envManager.get('REQUEST_LIMITER_QUEUE')),
|
|
193
|
+
limit: Number(envManager.get('REQUEST_LIMITER_LIMIT')),
|
|
194
|
+
}),
|
|
195
|
+
deps: {
|
|
196
|
+
envManager: tokensCommon.ENV_MANAGER_TOKEN,
|
|
197
|
+
},
|
|
198
|
+
}),
|
|
166
199
|
core.provide({
|
|
167
200
|
provide: REQUESTS_LIMITER_TOKEN,
|
|
168
201
|
scope: core.Scope.SINGLETON,
|
|
169
|
-
useFactory: ({ options, featureEnable }) => {
|
|
202
|
+
useFactory: ({ options, featureEnable, envManager }) => {
|
|
203
|
+
var _a, _b, _c, _d;
|
|
170
204
|
if (featureEnable === false) {
|
|
171
205
|
return;
|
|
172
206
|
}
|
|
173
|
-
|
|
207
|
+
const meld = envManager.get('REQUEST_LIMITER_MELD');
|
|
208
|
+
const queue = envManager.get('REQUEST_LIMITER_QUEUE');
|
|
209
|
+
const limit = envManager.get('REQUEST_LIMITER_LIMIT');
|
|
210
|
+
const resultOptions = {
|
|
211
|
+
limit: limit ? Number(limit) : (_a = options === null || options === void 0 ? void 0 : options.limit) !== null && _a !== void 0 ? _a : DEFAULT_OPTIONS.limit,
|
|
212
|
+
queue: queue ? Number(queue) : (_b = options === null || options === void 0 ? void 0 : options.queue) !== null && _b !== void 0 ? _b : DEFAULT_OPTIONS.queue,
|
|
213
|
+
maxEventLoopDelay: meld
|
|
214
|
+
? Number(meld)
|
|
215
|
+
: (_c = options === null || options === void 0 ? void 0 : options.maxEventLoopDelay) !== null && _c !== void 0 ? _c : DEFAULT_OPTIONS.maxEventLoopDelay,
|
|
216
|
+
error: (_d = options === null || options === void 0 ? void 0 : options.error) !== null && _d !== void 0 ? _d : DEFAULT_OPTIONS.error,
|
|
217
|
+
};
|
|
218
|
+
return new RequestLimiter(resultOptions);
|
|
174
219
|
},
|
|
175
220
|
deps: {
|
|
176
221
|
options: { token: REQUESTS_LIMITER_OPTIONS_TOKEN, optional: true },
|
|
177
222
|
featureEnable: { token: REQUESTS_LIMITER_ACTIVATE_TOKEN, optional: true },
|
|
223
|
+
envManager: tokensCommon.ENV_MANAGER_TOKEN,
|
|
178
224
|
},
|
|
179
225
|
}),
|
|
180
226
|
core.provide({
|
|
@@ -197,6 +243,7 @@ exports.RequestLimiterModule = tslib.__decorate([
|
|
|
197
243
|
})
|
|
198
244
|
], exports.RequestLimiterModule);
|
|
199
245
|
|
|
246
|
+
exports.DEFAULT_OPTIONS = DEFAULT_OPTIONS;
|
|
200
247
|
exports.REQUESTS_LIMITER_ACTIVATE_TOKEN = REQUESTS_LIMITER_ACTIVATE_TOKEN;
|
|
201
248
|
exports.REQUESTS_LIMITER_OPTIONS_TOKEN = REQUESTS_LIMITER_OPTIONS_TOKEN;
|
|
202
249
|
exports.REQUESTS_LIMITER_TOKEN = REQUESTS_LIMITER_TOKEN;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tramvai/module-request-limiter",
|
|
3
|
-
"version": "2.47.
|
|
3
|
+
"version": "2.47.2",
|
|
4
4
|
"description": "Enable different rendering modes for pages",
|
|
5
5
|
"main": "lib/server.js",
|
|
6
6
|
"module": "lib/server.es.js",
|
|
@@ -31,8 +31,9 @@
|
|
|
31
31
|
"devDependencies": {},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"@tinkoff/dippy": "0.8.9",
|
|
34
|
-
"@tramvai/core": "2.47.
|
|
35
|
-
"@tramvai/tokens-
|
|
34
|
+
"@tramvai/core": "2.47.2",
|
|
35
|
+
"@tramvai/tokens-common": "2.47.2",
|
|
36
|
+
"@tramvai/tokens-server-private": "2.47.2",
|
|
36
37
|
"fastify": "^4.6.0",
|
|
37
38
|
"tslib": "^2.4.0"
|
|
38
39
|
}
|