@tramvai/module-common 4.36.0 → 4.37.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 +79 -2
- package/lib/cache/CacheModule.browser.js +25 -23
- package/lib/cache/CacheModule.d.ts +0 -4
- package/lib/cache/CacheModule.es.js +25 -23
- package/lib/cache/CacheModule.js +22 -22
- package/lib/cache/cacheFactory.browser.browser.js +6 -4
- package/lib/cache/cacheFactory.browser.d.ts +3 -2
- package/lib/cache/cacheFactory.d.ts +5 -2
- package/lib/cache/cacheFactory.es.js +43 -17
- package/lib/cache/cacheFactory.js +43 -17
- package/lib/cache/cacheMetrics.d.ts +12 -0
- package/lib/cache/cacheMetrics.es.js +56 -0
- package/lib/cache/cacheMetrics.js +60 -0
- package/lib/cache/cacheOptions.browser.js +10 -0
- package/lib/cache/cacheOptions.d.ts +3 -0
- package/lib/cache/cacheOptions.es.js +10 -0
- package/lib/cache/cacheOptions.js +14 -0
- package/lib/cache/cacheRegistry.browser.js +14 -0
- package/lib/cache/cacheRegistry.d.ts +7 -0
- package/lib/cache/cacheRegistry.es.js +14 -0
- package/lib/cache/cacheRegistry.js +18 -0
- package/lib/cache/cacheType.d.ts +5 -0
- package/lib/cache/cacheType.es.js +10 -0
- package/lib/cache/cacheType.js +15 -0
- package/lib/cache/cacheWithMetricsProxy.d.ts +25 -0
- package/lib/cache/cacheWithMetricsProxy.es.js +74 -0
- package/lib/cache/cacheWithMetricsProxy.js +78 -0
- package/lib/cache/serverProviders.es.js +9 -1
- package/lib/cache/serverProviders.js +8 -0
- package/lib/cache/tokens.browser.js +8 -0
- package/lib/cache/tokens.d.ts +10 -0
- package/lib/cache/tokens.es.js +8 -0
- package/lib/cache/tokens.js +13 -0
- package/package.json +21 -20
package/README.md
CHANGED
|
@@ -65,12 +65,89 @@ Module that implements caches.
|
|
|
65
65
|
|
|
66
66
|
It provides next functionality:
|
|
67
67
|
|
|
68
|
-
- create new cache instance (
|
|
68
|
+
- create new cache instance (instance of lru-cache by default)
|
|
69
69
|
- clear all of the previously create caches
|
|
70
70
|
- subscribe on cache clearance event to execute own cache clearance actions
|
|
71
71
|
- adds papi-route `/clear-cache` that will trigger caches clear event
|
|
72
72
|
|
|
73
|
-
This modules logs
|
|
73
|
+
This modules logs with id `cache:papi-clear-cache`
|
|
74
|
+
|
|
75
|
+
##### Cache types
|
|
76
|
+
|
|
77
|
+
You can create different cache types with `CREATE_CACHE_TOKEN` factory:
|
|
78
|
+
|
|
79
|
+
- LRU - [@tinkoff/lru-cache-nano](https://github.com/tramvaijs/lru-cache-nano)
|
|
80
|
+
|
|
81
|
+
This type of cache is created by default. To create it explicitly you must pass `'memory'` as the first argument, and options as the second.
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
provide({
|
|
85
|
+
provide: CACHE_TOKEN,
|
|
86
|
+
scope: Scope.SINGLETON,
|
|
87
|
+
useFactory: ({ createCache }) =>
|
|
88
|
+
createCache('memory', {
|
|
89
|
+
max: 100,
|
|
90
|
+
ttl: 24 * 60 * 60 * 1000, // 1 day
|
|
91
|
+
ttlResolution: 60 * 1000, // 1 minute
|
|
92
|
+
allowStale: true,
|
|
93
|
+
updateAgeOnGet: true,
|
|
94
|
+
}),
|
|
95
|
+
deps: {
|
|
96
|
+
createCache: CREATE_CACHE_TOKEN,
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
- LFU - [@akashbabu/lfu-cache](https://github.com/AkashBabu/lfu-cache)
|
|
102
|
+
|
|
103
|
+
To create it you must pass `'memory-lfu'` as the first argument, cache options - as second.
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
provide({
|
|
107
|
+
provide: CACHE_TOKEN,
|
|
108
|
+
scope: Scope.SINGLETON,
|
|
109
|
+
useFactory: ({ createCache }) =>
|
|
110
|
+
createCache('memory-lfu', {
|
|
111
|
+
max: 20,
|
|
112
|
+
evictCount: 5,
|
|
113
|
+
maxAge: 24 * 60 * 60 * 1000, // 1 day
|
|
114
|
+
}),
|
|
115
|
+
deps: {
|
|
116
|
+
createCache: CREATE_CACHE_TOKEN,
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
##### Cache metrics
|
|
122
|
+
|
|
123
|
+
To turn cache hit/miss rate monitoring, cache size, you need to provide cache name in options:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
provide({
|
|
127
|
+
provide: CACHE_TOKEN,
|
|
128
|
+
scope: Scope.SINGLETON,
|
|
129
|
+
useFactory: ({ createCache }) =>
|
|
130
|
+
createCache('memory', {
|
|
131
|
+
name: 'cache-name',
|
|
132
|
+
}),
|
|
133
|
+
deps: {
|
|
134
|
+
createCache: CREATE_CACHE_TOKEN,
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Cache name have to be unique, factory will throw exception in case of cache name duplication.
|
|
140
|
+
|
|
141
|
+
[Metric module](references/modules/metrics.md) should be provided in your application.
|
|
142
|
+
|
|
143
|
+
Server cache metrics:
|
|
144
|
+
|
|
145
|
+
- cache_hit{name, method} counter
|
|
146
|
+
- cache_miss{name, method} counter
|
|
147
|
+
- cache_max{name} gauge
|
|
148
|
+
- cache_size{name} gauge
|
|
149
|
+
|
|
150
|
+
By default hit/miss rate is computed as a sum of all data access attempts (methods `has`, `peek`, `get`).
|
|
74
151
|
|
|
75
152
|
#### RequestManagerModule
|
|
76
153
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { __decorate } from 'tslib';
|
|
2
|
-
import {
|
|
2
|
+
import { provide } from '@tinkoff/dippy';
|
|
3
3
|
import { Module, Scope } from '@tramvai/core';
|
|
4
|
-
import { CREATE_CACHE_TOKEN, CLEAR_CACHE_TOKEN, REGISTER_CLEAR_CACHE_TOKEN } from '@tramvai/tokens-common';
|
|
5
|
-
import { cacheFactory } from './cacheFactory.browser.browser.js';
|
|
4
|
+
import { CREATE_CACHE_TOKEN, CACHE_METRICS_SERVER_TOKEN, CLEAR_CACHE_TOKEN, REGISTER_CLEAR_CACHE_TOKEN } from '@tramvai/tokens-common';
|
|
6
5
|
import { providers } from './clientProviders.browser.js';
|
|
6
|
+
import { cacheRegistry } from './cacheRegistry.browser.js';
|
|
7
|
+
import { CACHES_LIST_TOKEN, CACHE_NAMES_LIST_TOKEN } from './tokens.browser.js';
|
|
7
8
|
|
|
8
|
-
const cachesToken = createToken('_cachesList');
|
|
9
9
|
let CacheModule = class CacheModule {
|
|
10
10
|
};
|
|
11
11
|
CacheModule = __decorate([
|
|
@@ -13,43 +13,45 @@ CacheModule = __decorate([
|
|
|
13
13
|
providers: [
|
|
14
14
|
...providers,
|
|
15
15
|
{
|
|
16
|
-
provide:
|
|
16
|
+
provide: CACHES_LIST_TOKEN,
|
|
17
17
|
scope: Scope.SINGLETON,
|
|
18
18
|
useValue: [],
|
|
19
19
|
},
|
|
20
|
-
{
|
|
20
|
+
provide({
|
|
21
21
|
provide: CREATE_CACHE_TOKEN,
|
|
22
22
|
scope: Scope.SINGLETON,
|
|
23
|
-
useFactory:
|
|
24
|
-
return (type, ...args) => {
|
|
25
|
-
const cache = cacheFactory(type, ...args);
|
|
26
|
-
caches.push(cache);
|
|
27
|
-
return cache;
|
|
28
|
-
};
|
|
29
|
-
},
|
|
23
|
+
useFactory: cacheRegistry,
|
|
30
24
|
deps: {
|
|
31
|
-
caches:
|
|
25
|
+
caches: CACHES_LIST_TOKEN,
|
|
26
|
+
cacheNames: {
|
|
27
|
+
token: CACHE_NAMES_LIST_TOKEN,
|
|
28
|
+
optional: true,
|
|
29
|
+
},
|
|
30
|
+
metrics: {
|
|
31
|
+
token: CACHE_METRICS_SERVER_TOKEN,
|
|
32
|
+
optional: true,
|
|
33
|
+
},
|
|
32
34
|
},
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
+
}),
|
|
36
|
+
provide({
|
|
35
37
|
provide: CLEAR_CACHE_TOKEN,
|
|
36
38
|
scope: Scope.SINGLETON,
|
|
37
|
-
useFactory: ({ caches,
|
|
39
|
+
useFactory: ({ caches, onCacheClear }) => {
|
|
38
40
|
return (type) => {
|
|
39
41
|
caches.forEach((cache) => cache.clear());
|
|
40
|
-
if (
|
|
41
|
-
return Promise.all(
|
|
42
|
+
if (onCacheClear) {
|
|
43
|
+
return Promise.all(onCacheClear.map((clear) => clear(type)));
|
|
42
44
|
}
|
|
43
45
|
return Promise.resolve();
|
|
44
46
|
};
|
|
45
47
|
},
|
|
46
48
|
deps: {
|
|
47
|
-
caches:
|
|
48
|
-
|
|
49
|
+
caches: CACHES_LIST_TOKEN,
|
|
50
|
+
onCacheClear: { token: REGISTER_CLEAR_CACHE_TOKEN, optional: true },
|
|
49
51
|
},
|
|
50
|
-
},
|
|
52
|
+
}),
|
|
51
53
|
],
|
|
52
54
|
})
|
|
53
55
|
], CacheModule);
|
|
54
56
|
|
|
55
|
-
export { CacheModule
|
|
57
|
+
export { CacheModule };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { __decorate } from 'tslib';
|
|
2
|
-
import {
|
|
2
|
+
import { provide } from '@tinkoff/dippy';
|
|
3
3
|
import { Module, Scope } from '@tramvai/core';
|
|
4
|
-
import { CREATE_CACHE_TOKEN, CLEAR_CACHE_TOKEN, REGISTER_CLEAR_CACHE_TOKEN } from '@tramvai/tokens-common';
|
|
5
|
-
import { cacheFactory } from './cacheFactory.es.js';
|
|
4
|
+
import { CREATE_CACHE_TOKEN, CACHE_METRICS_SERVER_TOKEN, CLEAR_CACHE_TOKEN, REGISTER_CLEAR_CACHE_TOKEN } from '@tramvai/tokens-common';
|
|
6
5
|
import { providers } from './serverProviders.es.js';
|
|
6
|
+
import { cacheRegistry } from './cacheRegistry.es.js';
|
|
7
|
+
import { CACHES_LIST_TOKEN, CACHE_NAMES_LIST_TOKEN } from './tokens.es.js';
|
|
7
8
|
|
|
8
|
-
const cachesToken = createToken('_cachesList');
|
|
9
9
|
let CacheModule = class CacheModule {
|
|
10
10
|
};
|
|
11
11
|
CacheModule = __decorate([
|
|
@@ -13,43 +13,45 @@ CacheModule = __decorate([
|
|
|
13
13
|
providers: [
|
|
14
14
|
...providers,
|
|
15
15
|
{
|
|
16
|
-
provide:
|
|
16
|
+
provide: CACHES_LIST_TOKEN,
|
|
17
17
|
scope: Scope.SINGLETON,
|
|
18
18
|
useValue: [],
|
|
19
19
|
},
|
|
20
|
-
{
|
|
20
|
+
provide({
|
|
21
21
|
provide: CREATE_CACHE_TOKEN,
|
|
22
22
|
scope: Scope.SINGLETON,
|
|
23
|
-
useFactory:
|
|
24
|
-
return (type, ...args) => {
|
|
25
|
-
const cache = cacheFactory(type, ...args);
|
|
26
|
-
caches.push(cache);
|
|
27
|
-
return cache;
|
|
28
|
-
};
|
|
29
|
-
},
|
|
23
|
+
useFactory: cacheRegistry,
|
|
30
24
|
deps: {
|
|
31
|
-
caches:
|
|
25
|
+
caches: CACHES_LIST_TOKEN,
|
|
26
|
+
cacheNames: {
|
|
27
|
+
token: CACHE_NAMES_LIST_TOKEN,
|
|
28
|
+
optional: true,
|
|
29
|
+
},
|
|
30
|
+
metrics: {
|
|
31
|
+
token: CACHE_METRICS_SERVER_TOKEN,
|
|
32
|
+
optional: true,
|
|
33
|
+
},
|
|
32
34
|
},
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
+
}),
|
|
36
|
+
provide({
|
|
35
37
|
provide: CLEAR_CACHE_TOKEN,
|
|
36
38
|
scope: Scope.SINGLETON,
|
|
37
|
-
useFactory: ({ caches,
|
|
39
|
+
useFactory: ({ caches, onCacheClear }) => {
|
|
38
40
|
return (type) => {
|
|
39
41
|
caches.forEach((cache) => cache.clear());
|
|
40
|
-
if (
|
|
41
|
-
return Promise.all(
|
|
42
|
+
if (onCacheClear) {
|
|
43
|
+
return Promise.all(onCacheClear.map((clear) => clear(type)));
|
|
42
44
|
}
|
|
43
45
|
return Promise.resolve();
|
|
44
46
|
};
|
|
45
47
|
},
|
|
46
48
|
deps: {
|
|
47
|
-
caches:
|
|
48
|
-
|
|
49
|
+
caches: CACHES_LIST_TOKEN,
|
|
50
|
+
onCacheClear: { token: REGISTER_CLEAR_CACHE_TOKEN, optional: true },
|
|
49
51
|
},
|
|
50
|
-
},
|
|
52
|
+
}),
|
|
51
53
|
],
|
|
52
54
|
})
|
|
53
55
|
], CacheModule);
|
|
54
56
|
|
|
55
|
-
export { CacheModule
|
|
57
|
+
export { CacheModule };
|
package/lib/cache/CacheModule.js
CHANGED
|
@@ -6,10 +6,10 @@ var tslib = require('tslib');
|
|
|
6
6
|
var dippy = require('@tinkoff/dippy');
|
|
7
7
|
var core = require('@tramvai/core');
|
|
8
8
|
var tokensCommon = require('@tramvai/tokens-common');
|
|
9
|
-
var cacheFactory = require('./cacheFactory.js');
|
|
10
9
|
var serverProviders = require('./serverProviders.js');
|
|
10
|
+
var cacheRegistry = require('./cacheRegistry.js');
|
|
11
|
+
var tokens = require('./tokens.js');
|
|
11
12
|
|
|
12
|
-
const cachesToken = dippy.createToken('_cachesList');
|
|
13
13
|
exports.CacheModule = class CacheModule {
|
|
14
14
|
};
|
|
15
15
|
exports.CacheModule = tslib.__decorate([
|
|
@@ -17,43 +17,43 @@ exports.CacheModule = tslib.__decorate([
|
|
|
17
17
|
providers: [
|
|
18
18
|
...serverProviders.providers,
|
|
19
19
|
{
|
|
20
|
-
provide:
|
|
20
|
+
provide: tokens.CACHES_LIST_TOKEN,
|
|
21
21
|
scope: core.Scope.SINGLETON,
|
|
22
22
|
useValue: [],
|
|
23
23
|
},
|
|
24
|
-
{
|
|
24
|
+
dippy.provide({
|
|
25
25
|
provide: tokensCommon.CREATE_CACHE_TOKEN,
|
|
26
26
|
scope: core.Scope.SINGLETON,
|
|
27
|
-
useFactory:
|
|
28
|
-
return (type, ...args) => {
|
|
29
|
-
const cache = cacheFactory.cacheFactory(type, ...args);
|
|
30
|
-
caches.push(cache);
|
|
31
|
-
return cache;
|
|
32
|
-
};
|
|
33
|
-
},
|
|
27
|
+
useFactory: cacheRegistry.cacheRegistry,
|
|
34
28
|
deps: {
|
|
35
|
-
caches:
|
|
29
|
+
caches: tokens.CACHES_LIST_TOKEN,
|
|
30
|
+
cacheNames: {
|
|
31
|
+
token: tokens.CACHE_NAMES_LIST_TOKEN,
|
|
32
|
+
optional: true,
|
|
33
|
+
},
|
|
34
|
+
metrics: {
|
|
35
|
+
token: tokensCommon.CACHE_METRICS_SERVER_TOKEN,
|
|
36
|
+
optional: true,
|
|
37
|
+
},
|
|
36
38
|
},
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
+
}),
|
|
40
|
+
dippy.provide({
|
|
39
41
|
provide: tokensCommon.CLEAR_CACHE_TOKEN,
|
|
40
42
|
scope: core.Scope.SINGLETON,
|
|
41
|
-
useFactory: ({ caches,
|
|
43
|
+
useFactory: ({ caches, onCacheClear }) => {
|
|
42
44
|
return (type) => {
|
|
43
45
|
caches.forEach((cache) => cache.clear());
|
|
44
|
-
if (
|
|
45
|
-
return Promise.all(
|
|
46
|
+
if (onCacheClear) {
|
|
47
|
+
return Promise.all(onCacheClear.map((clear) => clear(type)));
|
|
46
48
|
}
|
|
47
49
|
return Promise.resolve();
|
|
48
50
|
};
|
|
49
51
|
},
|
|
50
52
|
deps: {
|
|
51
|
-
caches:
|
|
52
|
-
|
|
53
|
+
caches: tokens.CACHES_LIST_TOKEN,
|
|
54
|
+
onCacheClear: { token: tokensCommon.REGISTER_CLEAR_CACHE_TOKEN, optional: true },
|
|
53
55
|
},
|
|
54
|
-
},
|
|
56
|
+
}),
|
|
55
57
|
],
|
|
56
58
|
})
|
|
57
59
|
], exports.CacheModule);
|
|
58
|
-
|
|
59
|
-
exports.cachesToken = cachesToken;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import LRU from '@tinkoff/lru-cache-nano';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
return
|
|
5
|
-
|
|
3
|
+
function getCacheFactory() {
|
|
4
|
+
return function cacheFactory(cacheType = 'memory', options) {
|
|
5
|
+
return new LRU(options);
|
|
6
|
+
};
|
|
7
|
+
}
|
|
6
8
|
|
|
7
|
-
export {
|
|
9
|
+
export { getCacheFactory };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import LRU from '@tinkoff/lru-cache-nano';
|
|
2
|
+
import type { CacheOptions, CacheType } from '@tramvai/tokens-common';
|
|
3
|
+
export declare function getCacheFactory(): <T>(cacheType: CacheType | undefined, options: CacheOptions<CacheType>) => LRU<string, T>;
|
|
3
4
|
//# sourceMappingURL=cacheFactory.browser.d.ts.map
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare
|
|
1
|
+
import type { CacheOptions, Cache, CacheServerMetricsHandlers, CacheType } from '@tramvai/tokens-common';
|
|
2
|
+
export declare function getCacheFactory({ cacheNames, metrics, }: {
|
|
3
|
+
cacheNames: Set<string> | null;
|
|
4
|
+
metrics: CacheServerMetricsHandlers | null;
|
|
5
|
+
}): <T>(cacheType: CacheType, options: CacheOptions<CacheType>) => Cache<T>;
|
|
3
6
|
//# sourceMappingURL=cacheFactory.d.ts.map
|
|
@@ -1,34 +1,60 @@
|
|
|
1
1
|
import LRU from '@tinkoff/lru-cache-nano';
|
|
2
2
|
import LFU from '@akashbabu/lfu-cache';
|
|
3
|
+
import { MEMORY_LRU } from '@tramvai/tokens-common';
|
|
4
|
+
import { isMemoryLFU, isMemoryLRU } from './cacheType.es.js';
|
|
5
|
+
import { CacheWithMetricsProxy } from './cacheWithMetricsProxy.es.js';
|
|
3
6
|
|
|
4
7
|
class LFUToCacheAdapter extends LFU {
|
|
5
|
-
set(key, value, options) {
|
|
6
|
-
return this.set(key, value);
|
|
7
|
-
}
|
|
8
8
|
has(key) {
|
|
9
|
-
return typeof
|
|
9
|
+
return typeof super.get(key) !== 'undefined';
|
|
10
10
|
}
|
|
11
11
|
dump() {
|
|
12
12
|
const arr = [];
|
|
13
|
-
|
|
13
|
+
super.forEach(([key, value]) => arr.push([key, { value }]));
|
|
14
14
|
return arr;
|
|
15
15
|
}
|
|
16
16
|
load(arr) {
|
|
17
17
|
arr.forEach(([key, { value }]) => {
|
|
18
|
-
|
|
18
|
+
super.set(key, value);
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
|
|
23
|
-
if (type === 'memory-lfu') {
|
|
24
|
-
if (typeof options === 'object' && 'ttl' in options) {
|
|
25
|
-
// ttl option is not supported by @akashbabu/lfu-cache
|
|
26
|
-
// eslint-disable-next-line no-param-reassign
|
|
27
|
-
options.maxAge = options.ttl;
|
|
28
|
-
}
|
|
29
|
-
return new LFUToCacheAdapter(options);
|
|
30
|
-
}
|
|
22
|
+
function cacheFactoryMemoryLRU({ type, ...options }) {
|
|
31
23
|
return new LRU(options);
|
|
32
|
-
}
|
|
24
|
+
}
|
|
25
|
+
function cacheFactoryMemoryLFU({ type, ...options }) {
|
|
26
|
+
if (options && 'ttl' in options && typeof options.ttl === 'number') {
|
|
27
|
+
// ttl option is not supported by @akashbabu/lfu-cache
|
|
28
|
+
// eslint-disable-next-line no-param-reassign
|
|
29
|
+
options.maxAge = options.ttl;
|
|
30
|
+
}
|
|
31
|
+
return new LFUToCacheAdapter(options);
|
|
32
|
+
}
|
|
33
|
+
function cacheFactory(cacheType = MEMORY_LRU, options) {
|
|
34
|
+
let cache;
|
|
35
|
+
if (isMemoryLFU(options)) {
|
|
36
|
+
cache = cacheFactoryMemoryLFU(options);
|
|
37
|
+
}
|
|
38
|
+
if (isMemoryLRU(options)) {
|
|
39
|
+
cache = cacheFactoryMemoryLRU(options);
|
|
40
|
+
}
|
|
41
|
+
if (!cache) {
|
|
42
|
+
throw new Error(`Cache type ${cacheType} doesn't implemented yet`);
|
|
43
|
+
}
|
|
44
|
+
return cache;
|
|
45
|
+
}
|
|
46
|
+
function getCacheFactory({ cacheNames, metrics, }) {
|
|
47
|
+
return function (cacheType, options) {
|
|
48
|
+
const cache = cacheFactory(cacheType, options);
|
|
49
|
+
if (!(options === null || options === void 0 ? void 0 : options.name) || cacheNames === null) {
|
|
50
|
+
return cache;
|
|
51
|
+
}
|
|
52
|
+
if (cacheNames.has(options.name)) {
|
|
53
|
+
throw new Error(`Cache with name ${options.name} is already created`);
|
|
54
|
+
}
|
|
55
|
+
cacheNames.add(options.name);
|
|
56
|
+
return new CacheWithMetricsProxy(cache, options, metrics);
|
|
57
|
+
};
|
|
58
|
+
}
|
|
33
59
|
|
|
34
|
-
export {
|
|
60
|
+
export { getCacheFactory };
|
|
@@ -4,6 +4,9 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var LRU = require('@tinkoff/lru-cache-nano');
|
|
6
6
|
var LFU = require('@akashbabu/lfu-cache');
|
|
7
|
+
var tokensCommon = require('@tramvai/tokens-common');
|
|
8
|
+
var cacheType = require('./cacheType.js');
|
|
9
|
+
var cacheWithMetricsProxy = require('./cacheWithMetricsProxy.js');
|
|
7
10
|
|
|
8
11
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
9
12
|
|
|
@@ -11,33 +14,56 @@ var LRU__default = /*#__PURE__*/_interopDefaultLegacy(LRU);
|
|
|
11
14
|
var LFU__default = /*#__PURE__*/_interopDefaultLegacy(LFU);
|
|
12
15
|
|
|
13
16
|
class LFUToCacheAdapter extends LFU__default["default"] {
|
|
14
|
-
set(key, value, options) {
|
|
15
|
-
return this.set(key, value);
|
|
16
|
-
}
|
|
17
17
|
has(key) {
|
|
18
|
-
return typeof
|
|
18
|
+
return typeof super.get(key) !== 'undefined';
|
|
19
19
|
}
|
|
20
20
|
dump() {
|
|
21
21
|
const arr = [];
|
|
22
|
-
|
|
22
|
+
super.forEach(([key, value]) => arr.push([key, { value }]));
|
|
23
23
|
return arr;
|
|
24
24
|
}
|
|
25
25
|
load(arr) {
|
|
26
26
|
arr.forEach(([key, { value }]) => {
|
|
27
|
-
|
|
27
|
+
super.set(key, value);
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
-
|
|
32
|
-
if (type === 'memory-lfu') {
|
|
33
|
-
if (typeof options === 'object' && 'ttl' in options) {
|
|
34
|
-
// ttl option is not supported by @akashbabu/lfu-cache
|
|
35
|
-
// eslint-disable-next-line no-param-reassign
|
|
36
|
-
options.maxAge = options.ttl;
|
|
37
|
-
}
|
|
38
|
-
return new LFUToCacheAdapter(options);
|
|
39
|
-
}
|
|
31
|
+
function cacheFactoryMemoryLRU({ type, ...options }) {
|
|
40
32
|
return new LRU__default["default"](options);
|
|
41
|
-
}
|
|
33
|
+
}
|
|
34
|
+
function cacheFactoryMemoryLFU({ type, ...options }) {
|
|
35
|
+
if (options && 'ttl' in options && typeof options.ttl === 'number') {
|
|
36
|
+
// ttl option is not supported by @akashbabu/lfu-cache
|
|
37
|
+
// eslint-disable-next-line no-param-reassign
|
|
38
|
+
options.maxAge = options.ttl;
|
|
39
|
+
}
|
|
40
|
+
return new LFUToCacheAdapter(options);
|
|
41
|
+
}
|
|
42
|
+
function cacheFactory(cacheType$1 = tokensCommon.MEMORY_LRU, options) {
|
|
43
|
+
let cache;
|
|
44
|
+
if (cacheType.isMemoryLFU(options)) {
|
|
45
|
+
cache = cacheFactoryMemoryLFU(options);
|
|
46
|
+
}
|
|
47
|
+
if (cacheType.isMemoryLRU(options)) {
|
|
48
|
+
cache = cacheFactoryMemoryLRU(options);
|
|
49
|
+
}
|
|
50
|
+
if (!cache) {
|
|
51
|
+
throw new Error(`Cache type ${cacheType$1} doesn't implemented yet`);
|
|
52
|
+
}
|
|
53
|
+
return cache;
|
|
54
|
+
}
|
|
55
|
+
function getCacheFactory({ cacheNames, metrics, }) {
|
|
56
|
+
return function (cacheType, options) {
|
|
57
|
+
const cache = cacheFactory(cacheType, options);
|
|
58
|
+
if (!(options === null || options === void 0 ? void 0 : options.name) || cacheNames === null) {
|
|
59
|
+
return cache;
|
|
60
|
+
}
|
|
61
|
+
if (cacheNames.has(options.name)) {
|
|
62
|
+
throw new Error(`Cache with name ${options.name} is already created`);
|
|
63
|
+
}
|
|
64
|
+
cacheNames.add(options.name);
|
|
65
|
+
return new cacheWithMetricsProxy.CacheWithMetricsProxy(cache, options, metrics);
|
|
66
|
+
};
|
|
67
|
+
}
|
|
42
68
|
|
|
43
|
-
exports.
|
|
69
|
+
exports.getCacheFactory = getCacheFactory;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type CacheServerMetricsHandlers } from '@tramvai/tokens-common';
|
|
2
|
+
export declare const cacheMetricsServerProviders: import("@tinkoff/dippy").Provider<{
|
|
3
|
+
metrics: {
|
|
4
|
+
token: import("@tramvai/tokens-metrics").Metrics & {
|
|
5
|
+
__type?: "base token" | undefined;
|
|
6
|
+
};
|
|
7
|
+
optional: boolean;
|
|
8
|
+
};
|
|
9
|
+
}, CacheServerMetricsHandlers & {
|
|
10
|
+
__type?: "base token" | undefined;
|
|
11
|
+
}>[];
|
|
12
|
+
//# sourceMappingURL=cacheMetrics.d.ts.map
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { provide, Scope } from '@tinkoff/dippy';
|
|
2
|
+
import { CACHE_METRICS_SERVER_TOKEN } from '@tramvai/tokens-common';
|
|
3
|
+
import { METRICS_MODULE_TOKEN } from '@tramvai/tokens-metrics';
|
|
4
|
+
|
|
5
|
+
const cacheMetricsServerFactory = ({ metrics, }) => {
|
|
6
|
+
const cacheMetrics = metrics
|
|
7
|
+
? {
|
|
8
|
+
hitCounter: metrics.counter({
|
|
9
|
+
name: 'cache_hit',
|
|
10
|
+
help: 'Successful access to retrieve data from a cache.',
|
|
11
|
+
labelNames: ['name', 'method'],
|
|
12
|
+
}),
|
|
13
|
+
missCounter: metrics.counter({
|
|
14
|
+
name: 'cache_miss',
|
|
15
|
+
help: 'Failed request to retrieve data from a cache.',
|
|
16
|
+
labelNames: ['name', 'method'],
|
|
17
|
+
}),
|
|
18
|
+
cacheMaxGauge: metrics.gauge({
|
|
19
|
+
name: 'cache_max',
|
|
20
|
+
help: 'Maximum number of items in a cache.',
|
|
21
|
+
labelNames: ['name'],
|
|
22
|
+
}),
|
|
23
|
+
cacheSizeGauge: metrics.gauge({
|
|
24
|
+
name: 'cache_size',
|
|
25
|
+
help: 'The total number of items in a cache at the current moment.',
|
|
26
|
+
labelNames: ['name'],
|
|
27
|
+
}),
|
|
28
|
+
}
|
|
29
|
+
: undefined;
|
|
30
|
+
return {
|
|
31
|
+
onHit(name, method) {
|
|
32
|
+
cacheMetrics === null || cacheMetrics === void 0 ? void 0 : cacheMetrics.hitCounter.inc({ name, method });
|
|
33
|
+
},
|
|
34
|
+
onMiss(name, method) {
|
|
35
|
+
cacheMetrics === null || cacheMetrics === void 0 ? void 0 : cacheMetrics.missCounter.inc({ name, method });
|
|
36
|
+
},
|
|
37
|
+
onMax(name, size) {
|
|
38
|
+
cacheMetrics === null || cacheMetrics === void 0 ? void 0 : cacheMetrics.cacheMaxGauge.set({ name }, size);
|
|
39
|
+
},
|
|
40
|
+
onSize(name, size) {
|
|
41
|
+
cacheMetrics === null || cacheMetrics === void 0 ? void 0 : cacheMetrics.cacheSizeGauge.set({ name }, size);
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
const cacheMetricsServerProviders = [
|
|
46
|
+
provide({
|
|
47
|
+
provide: CACHE_METRICS_SERVER_TOKEN,
|
|
48
|
+
useFactory: cacheMetricsServerFactory,
|
|
49
|
+
scope: Scope.SINGLETON,
|
|
50
|
+
deps: {
|
|
51
|
+
metrics: { token: METRICS_MODULE_TOKEN, optional: true },
|
|
52
|
+
},
|
|
53
|
+
}),
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
export { cacheMetricsServerProviders };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var dippy = require('@tinkoff/dippy');
|
|
6
|
+
var tokensCommon = require('@tramvai/tokens-common');
|
|
7
|
+
var tokensMetrics = require('@tramvai/tokens-metrics');
|
|
8
|
+
|
|
9
|
+
const cacheMetricsServerFactory = ({ metrics, }) => {
|
|
10
|
+
const cacheMetrics = metrics
|
|
11
|
+
? {
|
|
12
|
+
hitCounter: metrics.counter({
|
|
13
|
+
name: 'cache_hit',
|
|
14
|
+
help: 'Successful access to retrieve data from a cache.',
|
|
15
|
+
labelNames: ['name', 'method'],
|
|
16
|
+
}),
|
|
17
|
+
missCounter: metrics.counter({
|
|
18
|
+
name: 'cache_miss',
|
|
19
|
+
help: 'Failed request to retrieve data from a cache.',
|
|
20
|
+
labelNames: ['name', 'method'],
|
|
21
|
+
}),
|
|
22
|
+
cacheMaxGauge: metrics.gauge({
|
|
23
|
+
name: 'cache_max',
|
|
24
|
+
help: 'Maximum number of items in a cache.',
|
|
25
|
+
labelNames: ['name'],
|
|
26
|
+
}),
|
|
27
|
+
cacheSizeGauge: metrics.gauge({
|
|
28
|
+
name: 'cache_size',
|
|
29
|
+
help: 'The total number of items in a cache at the current moment.',
|
|
30
|
+
labelNames: ['name'],
|
|
31
|
+
}),
|
|
32
|
+
}
|
|
33
|
+
: undefined;
|
|
34
|
+
return {
|
|
35
|
+
onHit(name, method) {
|
|
36
|
+
cacheMetrics === null || cacheMetrics === void 0 ? void 0 : cacheMetrics.hitCounter.inc({ name, method });
|
|
37
|
+
},
|
|
38
|
+
onMiss(name, method) {
|
|
39
|
+
cacheMetrics === null || cacheMetrics === void 0 ? void 0 : cacheMetrics.missCounter.inc({ name, method });
|
|
40
|
+
},
|
|
41
|
+
onMax(name, size) {
|
|
42
|
+
cacheMetrics === null || cacheMetrics === void 0 ? void 0 : cacheMetrics.cacheMaxGauge.set({ name }, size);
|
|
43
|
+
},
|
|
44
|
+
onSize(name, size) {
|
|
45
|
+
cacheMetrics === null || cacheMetrics === void 0 ? void 0 : cacheMetrics.cacheSizeGauge.set({ name }, size);
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
const cacheMetricsServerProviders = [
|
|
50
|
+
dippy.provide({
|
|
51
|
+
provide: tokensCommon.CACHE_METRICS_SERVER_TOKEN,
|
|
52
|
+
useFactory: cacheMetricsServerFactory,
|
|
53
|
+
scope: dippy.Scope.SINGLETON,
|
|
54
|
+
deps: {
|
|
55
|
+
metrics: { token: tokensMetrics.METRICS_MODULE_TOKEN, optional: true },
|
|
56
|
+
},
|
|
57
|
+
}),
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
exports.cacheMetricsServerProviders = cacheMetricsServerProviders;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CacheFactoryOptions, CacheOptions, CacheType } from '@tramvai/tokens-common';
|
|
2
|
+
export declare function getCacheOptions(cacheType: CacheType, options?: CacheFactoryOptions<typeof cacheType>): CacheOptions<typeof cacheType>;
|
|
3
|
+
//# sourceMappingURL=cacheOptions.d.ts.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
const CACHE_MAX_DEFAULT = 100;
|
|
6
|
+
function getCacheOptions(cacheType, options) {
|
|
7
|
+
return {
|
|
8
|
+
type: cacheType,
|
|
9
|
+
max: CACHE_MAX_DEFAULT,
|
|
10
|
+
...options,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
exports.getCacheOptions = getCacheOptions;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { getCacheOptions } from './cacheOptions.browser.js';
|
|
2
|
+
import { getCacheFactory } from './cacheFactory.browser.browser.js';
|
|
3
|
+
|
|
4
|
+
function cacheRegistry({ caches, cacheNames, metrics, }) {
|
|
5
|
+
return function (cacheType = 'memory', options) {
|
|
6
|
+
const extendedOptions = getCacheOptions(cacheType, options);
|
|
7
|
+
const factory = getCacheFactory();
|
|
8
|
+
const cache = factory(cacheType, extendedOptions);
|
|
9
|
+
caches.push(cache);
|
|
10
|
+
return cache;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { cacheRegistry };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Cache, CacheFactory, CacheServerMetricsHandlers } from '@tramvai/tokens-common';
|
|
2
|
+
export declare function cacheRegistry({ caches, cacheNames, metrics, }: {
|
|
3
|
+
caches: Cache[];
|
|
4
|
+
cacheNames: Set<string> | null;
|
|
5
|
+
metrics: CacheServerMetricsHandlers | null;
|
|
6
|
+
}): CacheFactory;
|
|
7
|
+
//# sourceMappingURL=cacheRegistry.d.ts.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { getCacheOptions } from './cacheOptions.es.js';
|
|
2
|
+
import { getCacheFactory } from './cacheFactory.es.js';
|
|
3
|
+
|
|
4
|
+
function cacheRegistry({ caches, cacheNames, metrics, }) {
|
|
5
|
+
return function (cacheType = 'memory', options) {
|
|
6
|
+
const extendedOptions = getCacheOptions(cacheType, options);
|
|
7
|
+
const factory = getCacheFactory({ cacheNames, metrics });
|
|
8
|
+
const cache = factory(cacheType, extendedOptions);
|
|
9
|
+
caches.push(cache);
|
|
10
|
+
return cache;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { cacheRegistry };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var cacheOptions = require('./cacheOptions.js');
|
|
6
|
+
var cacheFactory = require('./cacheFactory.js');
|
|
7
|
+
|
|
8
|
+
function cacheRegistry({ caches, cacheNames, metrics, }) {
|
|
9
|
+
return function (cacheType = 'memory', options) {
|
|
10
|
+
const extendedOptions = cacheOptions.getCacheOptions(cacheType, options);
|
|
11
|
+
const factory = cacheFactory.getCacheFactory({ cacheNames, metrics });
|
|
12
|
+
const cache = factory(cacheType, extendedOptions);
|
|
13
|
+
caches.push(cache);
|
|
14
|
+
return cache;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
exports.cacheRegistry = cacheRegistry;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { CacheOptions, CacheType } from '@tramvai/tokens-common';
|
|
2
|
+
import { MEMORY_LRU, MEMORY_LFU } from '@tramvai/tokens-common';
|
|
3
|
+
export declare function isMemoryLRU(options: CacheOptions<CacheType>): options is CacheOptions<typeof MEMORY_LRU>;
|
|
4
|
+
export declare function isMemoryLFU(options: CacheOptions<CacheType>): options is CacheOptions<typeof MEMORY_LFU>;
|
|
5
|
+
//# sourceMappingURL=cacheType.d.ts.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var tokensCommon = require('@tramvai/tokens-common');
|
|
6
|
+
|
|
7
|
+
function isMemoryLRU(options) {
|
|
8
|
+
return options.type === tokensCommon.MEMORY_LRU;
|
|
9
|
+
}
|
|
10
|
+
function isMemoryLFU(options) {
|
|
11
|
+
return options.type === tokensCommon.MEMORY_LFU;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
exports.isMemoryLFU = isMemoryLFU;
|
|
15
|
+
exports.isMemoryLRU = isMemoryLRU;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Cache, CacheOptions, CacheServerMetricsHandlers, CacheType } from '@tramvai/tokens-common';
|
|
2
|
+
export declare class CacheWithMetricsProxy<T> implements Cache<T> {
|
|
3
|
+
private cache;
|
|
4
|
+
private options;
|
|
5
|
+
private metrics;
|
|
6
|
+
constructor(cache: Cache, options: CacheOptions<CacheType> | undefined, metrics: CacheServerMetricsHandlers | null);
|
|
7
|
+
private handleAccess;
|
|
8
|
+
private syncSize;
|
|
9
|
+
get(key: string): T | undefined;
|
|
10
|
+
peek(key: string): T | undefined;
|
|
11
|
+
has(key: string): boolean;
|
|
12
|
+
set(key: string, value: T, options?: {
|
|
13
|
+
ttl?: number;
|
|
14
|
+
}): void;
|
|
15
|
+
delete(key: string): boolean;
|
|
16
|
+
clear(): void;
|
|
17
|
+
dump(): Array<[string, {
|
|
18
|
+
value: T;
|
|
19
|
+
}]>;
|
|
20
|
+
load(entries: Array<[string, {
|
|
21
|
+
value: T;
|
|
22
|
+
}]>): void;
|
|
23
|
+
get size(): number;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=cacheWithMetricsProxy.d.ts.map
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
class CacheWithMetricsProxy {
|
|
2
|
+
constructor(cache, options, metrics) {
|
|
3
|
+
var _a;
|
|
4
|
+
this.cache = cache;
|
|
5
|
+
this.options = options;
|
|
6
|
+
this.metrics = metrics;
|
|
7
|
+
if (this.options &&
|
|
8
|
+
this.options.name &&
|
|
9
|
+
'max' in this.options &&
|
|
10
|
+
typeof this.options.max === 'number') {
|
|
11
|
+
(_a = this.metrics) === null || _a === void 0 ? void 0 : _a.onMax(this.options.name, this.options.max);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
handleAccess(_key, value, method) {
|
|
15
|
+
var _a, _b, _c;
|
|
16
|
+
if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.name)) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (value) {
|
|
20
|
+
(_b = this.metrics) === null || _b === void 0 ? void 0 : _b.onHit(this.options.name, method);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
(_c = this.metrics) === null || _c === void 0 ? void 0 : _c.onMiss(this.options.name, method);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
syncSize() {
|
|
27
|
+
var _a, _b;
|
|
28
|
+
if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.name)) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
(_b = this.metrics) === null || _b === void 0 ? void 0 : _b.onSize(this.options.name, this.cache.size);
|
|
32
|
+
}
|
|
33
|
+
get(key) {
|
|
34
|
+
const value = this.cache.get(key);
|
|
35
|
+
this.handleAccess(key, value, 'get');
|
|
36
|
+
this.syncSize();
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
peek(key) {
|
|
40
|
+
const value = this.cache.peek(key);
|
|
41
|
+
this.handleAccess(key, value, 'peek');
|
|
42
|
+
return value;
|
|
43
|
+
}
|
|
44
|
+
has(key) {
|
|
45
|
+
const value = this.cache.has(key);
|
|
46
|
+
this.handleAccess(key, value, 'has');
|
|
47
|
+
return value;
|
|
48
|
+
}
|
|
49
|
+
set(key, value, options) {
|
|
50
|
+
this.cache.set(key, value, options);
|
|
51
|
+
this.syncSize();
|
|
52
|
+
}
|
|
53
|
+
delete(key) {
|
|
54
|
+
const result = this.cache.delete(key);
|
|
55
|
+
this.syncSize();
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
clear() {
|
|
59
|
+
this.cache.clear();
|
|
60
|
+
this.syncSize();
|
|
61
|
+
}
|
|
62
|
+
dump() {
|
|
63
|
+
return this.cache.dump();
|
|
64
|
+
}
|
|
65
|
+
load(entries) {
|
|
66
|
+
this.cache.load(entries);
|
|
67
|
+
this.syncSize();
|
|
68
|
+
}
|
|
69
|
+
get size() {
|
|
70
|
+
return this.cache.size;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export { CacheWithMetricsProxy };
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
class CacheWithMetricsProxy {
|
|
6
|
+
constructor(cache, options, metrics) {
|
|
7
|
+
var _a;
|
|
8
|
+
this.cache = cache;
|
|
9
|
+
this.options = options;
|
|
10
|
+
this.metrics = metrics;
|
|
11
|
+
if (this.options &&
|
|
12
|
+
this.options.name &&
|
|
13
|
+
'max' in this.options &&
|
|
14
|
+
typeof this.options.max === 'number') {
|
|
15
|
+
(_a = this.metrics) === null || _a === void 0 ? void 0 : _a.onMax(this.options.name, this.options.max);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
handleAccess(_key, value, method) {
|
|
19
|
+
var _a, _b, _c;
|
|
20
|
+
if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.name)) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (value) {
|
|
24
|
+
(_b = this.metrics) === null || _b === void 0 ? void 0 : _b.onHit(this.options.name, method);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
(_c = this.metrics) === null || _c === void 0 ? void 0 : _c.onMiss(this.options.name, method);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
syncSize() {
|
|
31
|
+
var _a, _b;
|
|
32
|
+
if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.name)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
(_b = this.metrics) === null || _b === void 0 ? void 0 : _b.onSize(this.options.name, this.cache.size);
|
|
36
|
+
}
|
|
37
|
+
get(key) {
|
|
38
|
+
const value = this.cache.get(key);
|
|
39
|
+
this.handleAccess(key, value, 'get');
|
|
40
|
+
this.syncSize();
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
peek(key) {
|
|
44
|
+
const value = this.cache.peek(key);
|
|
45
|
+
this.handleAccess(key, value, 'peek');
|
|
46
|
+
return value;
|
|
47
|
+
}
|
|
48
|
+
has(key) {
|
|
49
|
+
const value = this.cache.has(key);
|
|
50
|
+
this.handleAccess(key, value, 'has');
|
|
51
|
+
return value;
|
|
52
|
+
}
|
|
53
|
+
set(key, value, options) {
|
|
54
|
+
this.cache.set(key, value, options);
|
|
55
|
+
this.syncSize();
|
|
56
|
+
}
|
|
57
|
+
delete(key) {
|
|
58
|
+
const result = this.cache.delete(key);
|
|
59
|
+
this.syncSize();
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
clear() {
|
|
63
|
+
this.cache.clear();
|
|
64
|
+
this.syncSize();
|
|
65
|
+
}
|
|
66
|
+
dump() {
|
|
67
|
+
return this.cache.dump();
|
|
68
|
+
}
|
|
69
|
+
load(entries) {
|
|
70
|
+
this.cache.load(entries);
|
|
71
|
+
this.syncSize();
|
|
72
|
+
}
|
|
73
|
+
get size() {
|
|
74
|
+
return this.cache.size;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
exports.CacheWithMetricsProxy = CacheWithMetricsProxy;
|
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
import { provide } from '@tramvai/core';
|
|
1
|
+
import { provide, Scope } from '@tramvai/core';
|
|
2
2
|
import { SERVER_MODULE_PAPI_PRIVATE_ROUTE } from '@tramvai/tokens-server';
|
|
3
3
|
import { CLEAR_CACHE_TOKEN, LOGGER_TOKEN } from '@tramvai/tokens-common';
|
|
4
4
|
import { papiClearCache } from './papi.es.js';
|
|
5
|
+
import { CACHE_NAMES_LIST_TOKEN } from './tokens.es.js';
|
|
6
|
+
import { cacheMetricsServerProviders } from './cacheMetrics.es.js';
|
|
5
7
|
|
|
6
8
|
const providers = [
|
|
9
|
+
...cacheMetricsServerProviders,
|
|
10
|
+
provide({
|
|
11
|
+
provide: CACHE_NAMES_LIST_TOKEN,
|
|
12
|
+
scope: Scope.SINGLETON,
|
|
13
|
+
useValue: new Set(),
|
|
14
|
+
}),
|
|
7
15
|
provide({
|
|
8
16
|
provide: SERVER_MODULE_PAPI_PRIVATE_ROUTE,
|
|
9
17
|
multi: true,
|
|
@@ -6,8 +6,16 @@ var core = require('@tramvai/core');
|
|
|
6
6
|
var tokensServer = require('@tramvai/tokens-server');
|
|
7
7
|
var tokensCommon = require('@tramvai/tokens-common');
|
|
8
8
|
var papi = require('./papi.js');
|
|
9
|
+
var tokens = require('./tokens.js');
|
|
10
|
+
var cacheMetrics = require('./cacheMetrics.js');
|
|
9
11
|
|
|
10
12
|
const providers = [
|
|
13
|
+
...cacheMetrics.cacheMetricsServerProviders,
|
|
14
|
+
core.provide({
|
|
15
|
+
provide: tokens.CACHE_NAMES_LIST_TOKEN,
|
|
16
|
+
scope: core.Scope.SINGLETON,
|
|
17
|
+
useValue: new Set(),
|
|
18
|
+
}),
|
|
11
19
|
core.provide({
|
|
12
20
|
provide: tokensServer.SERVER_MODULE_PAPI_PRIVATE_ROUTE,
|
|
13
21
|
multi: true,
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { createToken } from '@tinkoff/dippy';
|
|
2
|
+
|
|
3
|
+
/** Is used to perform all app caches clearing */
|
|
4
|
+
const CACHES_LIST_TOKEN = createToken('_cachesList');
|
|
5
|
+
/** Is used to check the uniqueness of metrics labels */
|
|
6
|
+
const CACHE_NAMES_LIST_TOKEN = createToken('cache names list');
|
|
7
|
+
|
|
8
|
+
export { CACHES_LIST_TOKEN, CACHE_NAMES_LIST_TOKEN };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Cache } from '@tramvai/tokens-common';
|
|
2
|
+
/** Is used to perform all app caches clearing */
|
|
3
|
+
export declare const CACHES_LIST_TOKEN: Cache<any>[] & {
|
|
4
|
+
__type?: "base token" | undefined;
|
|
5
|
+
};
|
|
6
|
+
/** Is used to check the uniqueness of metrics labels */
|
|
7
|
+
export declare const CACHE_NAMES_LIST_TOKEN: Set<string> & {
|
|
8
|
+
__type?: "base token" | undefined;
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=tokens.d.ts.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { createToken } from '@tinkoff/dippy';
|
|
2
|
+
|
|
3
|
+
/** Is used to perform all app caches clearing */
|
|
4
|
+
const CACHES_LIST_TOKEN = createToken('_cachesList');
|
|
5
|
+
/** Is used to check the uniqueness of metrics labels */
|
|
6
|
+
const CACHE_NAMES_LIST_TOKEN = createToken('cache names list');
|
|
7
|
+
|
|
8
|
+
export { CACHES_LIST_TOKEN, CACHE_NAMES_LIST_TOKEN };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var dippy = require('@tinkoff/dippy');
|
|
6
|
+
|
|
7
|
+
/** Is used to perform all app caches clearing */
|
|
8
|
+
const CACHES_LIST_TOKEN = dippy.createToken('_cachesList');
|
|
9
|
+
/** Is used to check the uniqueness of metrics labels */
|
|
10
|
+
const CACHE_NAMES_LIST_TOKEN = dippy.createToken('cache names list');
|
|
11
|
+
|
|
12
|
+
exports.CACHES_LIST_TOKEN = CACHES_LIST_TOKEN;
|
|
13
|
+
exports.CACHE_NAMES_LIST_TOKEN = CACHE_NAMES_LIST_TOKEN;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tramvai/module-common",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.37.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
@@ -30,36 +30,37 @@
|
|
|
30
30
|
"watch": "tsc -w"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
+
"@akashbabu/lfu-cache": "1.0.2",
|
|
33
34
|
"@tinkoff/errors": "0.5.1",
|
|
34
35
|
"@tinkoff/hook-runner": "0.6.1",
|
|
35
36
|
"@tinkoff/lru-cache-nano": "^7.9.0",
|
|
36
|
-
"@akashbabu/lfu-cache": "1.0.2",
|
|
37
37
|
"@tinkoff/pubsub": "0.7.1",
|
|
38
38
|
"@tinkoff/url": "0.10.1",
|
|
39
|
-
"@tramvai/
|
|
40
|
-
"@tramvai/
|
|
41
|
-
"@tramvai/module-
|
|
42
|
-
"@tramvai/module-
|
|
43
|
-
"@tramvai/
|
|
44
|
-
"@tramvai/tokens-child-app": "4.
|
|
45
|
-
"@tramvai/tokens-
|
|
46
|
-
"@tramvai/tokens-
|
|
47
|
-
"@tramvai/tokens-
|
|
48
|
-
"@tramvai/tokens-
|
|
49
|
-
"@tramvai/tokens-
|
|
50
|
-
"@tramvai/
|
|
39
|
+
"@tramvai/experiments": "4.37.0",
|
|
40
|
+
"@tramvai/module-cookie": "4.37.0",
|
|
41
|
+
"@tramvai/module-environment": "4.37.0",
|
|
42
|
+
"@tramvai/module-log": "4.37.0",
|
|
43
|
+
"@tramvai/safe-strings": "0.7.3",
|
|
44
|
+
"@tramvai/tokens-child-app": "4.37.0",
|
|
45
|
+
"@tramvai/tokens-common": "4.37.0",
|
|
46
|
+
"@tramvai/tokens-core-private": "4.37.0",
|
|
47
|
+
"@tramvai/tokens-metrics": "4.37.0",
|
|
48
|
+
"@tramvai/tokens-render": "4.37.0",
|
|
49
|
+
"@tramvai/tokens-router": "4.37.0",
|
|
50
|
+
"@tramvai/tokens-server-private": "4.37.0",
|
|
51
|
+
"@tramvai/types-actions-state-context": "4.37.0",
|
|
51
52
|
"hoist-non-react-statics": "^3.3.1",
|
|
52
53
|
"node-abort-controller": "^3.0.1"
|
|
53
54
|
},
|
|
54
55
|
"peerDependencies": {
|
|
55
56
|
"@tinkoff/dippy": "0.10.8",
|
|
56
57
|
"@tinkoff/utils": "^2.1.2",
|
|
57
|
-
"@tramvai/cli": "4.
|
|
58
|
-
"@tramvai/core": "4.
|
|
59
|
-
"@tramvai/papi": "4.
|
|
60
|
-
"@tramvai/react": "4.
|
|
61
|
-
"@tramvai/state": "4.
|
|
62
|
-
"@tramvai/tokens-server": "4.
|
|
58
|
+
"@tramvai/cli": "4.37.0",
|
|
59
|
+
"@tramvai/core": "4.37.0",
|
|
60
|
+
"@tramvai/papi": "4.37.0",
|
|
61
|
+
"@tramvai/react": "4.37.0",
|
|
62
|
+
"@tramvai/state": "4.37.0",
|
|
63
|
+
"@tramvai/tokens-server": "4.37.0",
|
|
63
64
|
"react": ">=16.14.0",
|
|
64
65
|
"tslib": "^2.4.0"
|
|
65
66
|
},
|