@tramvai/module-dns-cache 2.117.0

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 ADDED
@@ -0,0 +1,64 @@
1
+ # @tramvai/module-dns-cache
2
+
3
+
4
+ DNS lookup cache for Node.js - [cacheable-lookup](https://github.com/szmarczak/cacheable-lookup) library integration.
5
+
6
+ ## Explanation
7
+
8
+ DNS lookup cache can speed up your server-side HTTP requests to external API's.
9
+
10
+ Usually, DNS lookup is a fast process, but Node.js (`libuv` under the hood) has a [default limit of 4 concurrent threads](https://nodejs.org/docs/latest-v18.x/api/cli.html#uv_threadpool_sizesize), used for a [set of synchronous operations](https://nodejs.org/en/docs/guides/dont-block-the-event-loop), including DNS lookup, so lookup can be queued. Or if application is under high load, or while any network problems, DNS lookup time can be increased.
11
+
12
+ First main optimization of HTTP connections is already used in `tramvai` [HTTP clients](03-features/09-data-fetching/02-http-client.md) - [keepAlive option](https://nodejs.org/api/http.html#new-agentoptions) for `http` and `https` agents. With `keepAlive`, TCP sockets are reused for multiple HTTP requests, and count of DNS lookups is decreased dramatically.
13
+
14
+ Because of that, DNS cache it's a nice and cheap optimization, but don't expect some huge performance boost.
15
+
16
+ Potential disadvantages - external services can change their IP addresses, and HTTP requests will use outdated DNS cache, you can detect this by search `ENOTFOUND` errors is server logs, so long cache TTL is not recommended.
17
+
18
+ ## Installation
19
+
20
+ You need to install `@tramvai/module-dns-cache` module:
21
+
22
+ ```bash
23
+ npx tramvai add @tramvai/module-dns-cache
24
+ ```
25
+
26
+ Then, connect `TramvaiDnsCacheModule` from this package to `createApp` function:
27
+
28
+ ```ts
29
+ import { createApp } from '@tramvai/core';
30
+ import { TramvaiDnsCacheModule } from '@tramvai/module-dns-cache';
31
+
32
+ createApp({
33
+ name: 'tincoin',
34
+ modules: [TramvaiDnsCacheModule],
35
+ });
36
+ ```
37
+
38
+ ## Configuration
39
+
40
+ ### Enable/disable
41
+
42
+ By default, DNS lookup cache is **enabled**.
43
+
44
+ To disable it, you need to provide `DNS_LOOKUP_CACHE_ENABLE` environment variable:
45
+
46
+ ```bash
47
+ DNS_LOOKUP_CACHE_ENABLE=false
48
+ ```
49
+
50
+ ### Cache TTL
51
+
52
+ Default TTL for DNS lookup cache is 60 seconds. You can change it by providing `DNS_LOOKUP_CACHE_TTL` environment variable:
53
+
54
+ ```bash
55
+ DNS_LOOKUP_CACHE_TTL=120000
56
+ ```
57
+
58
+ ### Cache size
59
+
60
+ Default cache size is 200 entries. You can change it by providing `DNS_LOOKUP_CACHE_LIMIT` environment variable:
61
+
62
+ ```bash
63
+ DNS_LOOKUP_CACHE_LIMIT=500
64
+ ```
@@ -0,0 +1,3 @@
1
+ export declare const TramvaiDnsCacheModule: import("@tinkoff/dippy/lib/modules/module.h").ModuleClass & Partial<import("@tinkoff/dippy/lib/modules/module.h").ModuleSecretParameters> & {
2
+ [x: string]: (...args: any[]) => import("@tramvai/core").ModuleType<import("@tinkoff/dippy/lib/modules/module.h").ModuleClass>;
3
+ };
package/lib/browser.js ADDED
@@ -0,0 +1,9 @@
1
+ import { declareModule } from '@tramvai/core';
2
+
3
+ const TramvaiDnsCacheModule = declareModule({
4
+ name: 'TramvaiDnsCacheModule',
5
+ imports: [],
6
+ providers: [],
7
+ });
8
+
9
+ export { TramvaiDnsCacheModule };
@@ -0,0 +1,3 @@
1
+ export declare const TramvaiDnsCacheModule: import("@tinkoff/dippy/lib/modules/module.h").ModuleClass & Partial<import("@tinkoff/dippy/lib/modules/module.h").ModuleSecretParameters> & {
2
+ [x: string]: (...args: any[]) => import("@tramvai/core").ModuleType<import("@tinkoff/dippy/lib/modules/module.h").ModuleClass>;
3
+ };
@@ -0,0 +1,81 @@
1
+ import noop from '@tinkoff/utils/function/noop';
2
+ import http from 'http';
3
+ import https from 'https';
4
+ import dns from 'dns';
5
+ import CacheableLookup from 'cacheable-lookup';
6
+ import { createToken, declareModule, provide, commandLineListTokens, Scope } from '@tramvai/core';
7
+ import { ENV_MANAGER_TOKEN, CREATE_CACHE_TOKEN, ENV_USED_TOKEN } from '@tramvai/tokens-common';
8
+
9
+ const DNS_LOOKUP_CACHE_TOKEN = createToken('dnsLookupCache');
10
+ const TramvaiDnsCacheModule = declareModule({
11
+ name: 'TramvaiDnsCacheModule',
12
+ imports: [],
13
+ providers: [
14
+ provide({
15
+ provide: commandLineListTokens.init,
16
+ multi: true,
17
+ useFactory: ({ envManager, cache }) => {
18
+ if (envManager.get('DNS_LOOKUP_CACHE_ENABLE') !== 'true') {
19
+ return noop;
20
+ }
21
+ return () => {
22
+ const maxTtl = Number(envManager.get('DNS_LOOKUP_CACHE_TTL'));
23
+ const cacheable = new CacheableLookup({
24
+ cache,
25
+ maxTtl,
26
+ });
27
+ const originalLookup = cacheable.lookup;
28
+ // workaround for https://github.com/szmarczak/cacheable-lookup/issues/68,
29
+ // use original dns.lookup for localhost because cacheable-lookup doesn't handle `ESERVFAIL` error when resolving ipv6
30
+ // @ts-expect-error
31
+ cacheable.lookup = (hostname, options, callback) => {
32
+ if (hostname === 'localhost') {
33
+ return dns.lookup(hostname, options, callback);
34
+ }
35
+ originalLookup.call(cacheable, hostname, options, callback);
36
+ };
37
+ cacheable.install(http.globalAgent);
38
+ cacheable.install(https.globalAgent);
39
+ };
40
+ },
41
+ deps: {
42
+ envManager: ENV_MANAGER_TOKEN,
43
+ cache: DNS_LOOKUP_CACHE_TOKEN,
44
+ },
45
+ }),
46
+ provide({
47
+ provide: DNS_LOOKUP_CACHE_TOKEN,
48
+ scope: Scope.SINGLETON,
49
+ useFactory: ({ createCache, envManager }) => {
50
+ const max = Number(envManager.get('DNS_LOOKUP_CACHE_LIMIT'));
51
+ const ttl = Number(envManager.get('DNS_LOOKUP_CACHE_TTL'));
52
+ return createCache('memory', { max, ttl });
53
+ },
54
+ deps: {
55
+ createCache: CREATE_CACHE_TOKEN,
56
+ envManager: ENV_MANAGER_TOKEN,
57
+ },
58
+ }),
59
+ provide({
60
+ provide: ENV_USED_TOKEN,
61
+ multi: true,
62
+ useValue: [
63
+ { key: 'DNS_LOOKUP_CACHE_ENABLE', dehydrate: false, optional: true, value: 'true' },
64
+ {
65
+ key: 'DNS_LOOKUP_CACHE_LIMIT',
66
+ value: '200',
67
+ dehydrate: false,
68
+ optional: true,
69
+ },
70
+ {
71
+ key: 'DNS_LOOKUP_CACHE_TTL',
72
+ value: '60000',
73
+ dehydrate: false,
74
+ optional: true,
75
+ },
76
+ ],
77
+ }),
78
+ ],
79
+ });
80
+
81
+ export { TramvaiDnsCacheModule };
package/lib/server.js ADDED
@@ -0,0 +1,93 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var noop = require('@tinkoff/utils/function/noop');
6
+ var http = require('http');
7
+ var https = require('https');
8
+ var dns = require('dns');
9
+ var CacheableLookup = require('cacheable-lookup');
10
+ var core = require('@tramvai/core');
11
+ var tokensCommon = require('@tramvai/tokens-common');
12
+
13
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
14
+
15
+ var noop__default = /*#__PURE__*/_interopDefaultLegacy(noop);
16
+ var http__default = /*#__PURE__*/_interopDefaultLegacy(http);
17
+ var https__default = /*#__PURE__*/_interopDefaultLegacy(https);
18
+ var dns__default = /*#__PURE__*/_interopDefaultLegacy(dns);
19
+ var CacheableLookup__default = /*#__PURE__*/_interopDefaultLegacy(CacheableLookup);
20
+
21
+ const DNS_LOOKUP_CACHE_TOKEN = core.createToken('dnsLookupCache');
22
+ const TramvaiDnsCacheModule = core.declareModule({
23
+ name: 'TramvaiDnsCacheModule',
24
+ imports: [],
25
+ providers: [
26
+ core.provide({
27
+ provide: core.commandLineListTokens.init,
28
+ multi: true,
29
+ useFactory: ({ envManager, cache }) => {
30
+ if (envManager.get('DNS_LOOKUP_CACHE_ENABLE') !== 'true') {
31
+ return noop__default["default"];
32
+ }
33
+ return () => {
34
+ const maxTtl = Number(envManager.get('DNS_LOOKUP_CACHE_TTL'));
35
+ const cacheable = new CacheableLookup__default["default"]({
36
+ cache,
37
+ maxTtl,
38
+ });
39
+ const originalLookup = cacheable.lookup;
40
+ // workaround for https://github.com/szmarczak/cacheable-lookup/issues/68,
41
+ // use original dns.lookup for localhost because cacheable-lookup doesn't handle `ESERVFAIL` error when resolving ipv6
42
+ // @ts-expect-error
43
+ cacheable.lookup = (hostname, options, callback) => {
44
+ if (hostname === 'localhost') {
45
+ return dns__default["default"].lookup(hostname, options, callback);
46
+ }
47
+ originalLookup.call(cacheable, hostname, options, callback);
48
+ };
49
+ cacheable.install(http__default["default"].globalAgent);
50
+ cacheable.install(https__default["default"].globalAgent);
51
+ };
52
+ },
53
+ deps: {
54
+ envManager: tokensCommon.ENV_MANAGER_TOKEN,
55
+ cache: DNS_LOOKUP_CACHE_TOKEN,
56
+ },
57
+ }),
58
+ core.provide({
59
+ provide: DNS_LOOKUP_CACHE_TOKEN,
60
+ scope: core.Scope.SINGLETON,
61
+ useFactory: ({ createCache, envManager }) => {
62
+ const max = Number(envManager.get('DNS_LOOKUP_CACHE_LIMIT'));
63
+ const ttl = Number(envManager.get('DNS_LOOKUP_CACHE_TTL'));
64
+ return createCache('memory', { max, ttl });
65
+ },
66
+ deps: {
67
+ createCache: tokensCommon.CREATE_CACHE_TOKEN,
68
+ envManager: tokensCommon.ENV_MANAGER_TOKEN,
69
+ },
70
+ }),
71
+ core.provide({
72
+ provide: tokensCommon.ENV_USED_TOKEN,
73
+ multi: true,
74
+ useValue: [
75
+ { key: 'DNS_LOOKUP_CACHE_ENABLE', dehydrate: false, optional: true, value: 'true' },
76
+ {
77
+ key: 'DNS_LOOKUP_CACHE_LIMIT',
78
+ value: '200',
79
+ dehydrate: false,
80
+ optional: true,
81
+ },
82
+ {
83
+ key: 'DNS_LOOKUP_CACHE_TTL',
84
+ value: '60000',
85
+ dehydrate: false,
86
+ optional: true,
87
+ },
88
+ ],
89
+ }),
90
+ ],
91
+ });
92
+
93
+ exports.TramvaiDnsCacheModule = TramvaiDnsCacheModule;
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@tramvai/module-dns-cache",
3
+ "version": "2.117.0",
4
+ "description": "DNS lookup cache",
5
+ "browser": "lib/browser.js",
6
+ "main": "lib/server.js",
7
+ "module": "lib/server.es.js",
8
+ "typings": "lib/server.d.ts",
9
+ "files": [
10
+ "lib"
11
+ ],
12
+ "sideEffects": false,
13
+ "license": "Apache-2.0",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git@github.com:Tinkoff/tramvai.git"
17
+ },
18
+ "scripts": {
19
+ "build": "tramvai-build --forPublish --preserveModules",
20
+ "watch": "tsc -w"
21
+ },
22
+ "publishConfig": {
23
+ "registry": "https://registry.npmjs.org/"
24
+ },
25
+ "dependencies": {
26
+ "@tinkoff/utils": "^2.1.2",
27
+ "@tramvai/core": "2.117.0",
28
+ "@tramvai/tokens-common": "2.117.0",
29
+ "cacheable-lookup": "^7.0.0"
30
+ },
31
+ "devDependencies": {},
32
+ "peerDependencies": {
33
+ "tslib": "^2.4.0"
34
+ }
35
+ }