@chainlink/external-adapter-framework 0.0.8 → 0.0.12
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/.c8rc.json +3 -0
- package/.eslintignore +9 -0
- package/.eslintrc.js +96 -0
- package/.github/README.MD +17 -0
- package/.github/actions/setup/action.yaml +13 -0
- package/.github/workflows/main.yaml +39 -0
- package/.github/workflows/publish.yaml +20 -0
- package/.prettierignore +13 -0
- package/.yarnrc +0 -0
- package/README.md +103 -0
- package/dist/src/adapter.d.ts +135 -0
- package/dist/src/adapter.js +145 -0
- package/{package → dist/src}/background-executor.d.ts +2 -2
- package/{background-executor.js → dist/src/background-executor.js} +0 -0
- package/{cache → dist/src/cache}/factory.d.ts +0 -0
- package/{package → dist/src}/cache/factory.js +0 -2
- package/{package → dist/src}/cache/index.d.ts +10 -6
- package/{package → dist/src}/cache/index.js +13 -9
- package/{cache → dist/src/cache}/local.d.ts +0 -0
- package/{cache → dist/src/cache}/local.js +0 -0
- package/{cache → dist/src/cache}/metrics.d.ts +0 -0
- package/{cache → dist/src/cache}/metrics.js +0 -0
- package/{cache → dist/src/cache}/redis.d.ts +0 -0
- package/{package → dist/src}/cache/redis.js +5 -5
- package/dist/src/chainlink-external-adapter-framework-0.0.6.tgz +0 -0
- package/{package → dist/src}/config/index.d.ts +20 -1
- package/{package → dist/src}/config/index.js +24 -9
- package/{config → dist/src/config}/provider-limits.d.ts +0 -0
- package/{config → dist/src/config}/provider-limits.js +0 -0
- package/dist/src/examples/bank-frick/accounts.d.ts +39 -0
- package/dist/src/examples/bank-frick/accounts.js +192 -0
- package/dist/src/examples/bank-frick/config/index.d.ts +4 -0
- package/dist/src/examples/bank-frick/config/index.js +54 -0
- package/dist/src/examples/bank-frick/index.d.ts +2 -0
- package/dist/src/examples/bank-frick/index.js +15 -0
- package/dist/src/examples/bank-frick/util.d.ts +4 -0
- package/dist/src/examples/bank-frick/util.js +39 -0
- package/dist/src/examples/coingecko/batch-warming.d.ts +7 -0
- package/{package → dist/src}/examples/coingecko/batch-warming.js +3 -2
- package/dist/src/examples/coingecko/index.d.ts +2 -0
- package/{package → dist/src}/examples/coingecko/index.js +3 -2
- package/dist/src/examples/coingecko/rest.d.ts +12 -0
- package/{package → dist/src}/examples/coingecko/rest.js +3 -2
- package/{examples → dist/src/examples}/ncfx/config/index.d.ts +0 -0
- package/{examples → dist/src/examples}/ncfx/config/index.js +0 -0
- package/dist/src/examples/ncfx/index.d.ts +13 -0
- package/{package → dist/src}/examples/ncfx/index.js +3 -2
- package/{package → dist/src}/examples/ncfx/websocket.d.ts +12 -1
- package/{package → dist/src}/examples/ncfx/websocket.js +3 -2
- package/{package → dist/src}/index.d.ts +2 -3
- package/{package → dist/src}/index.js +55 -19
- package/{metrics → dist/src/metrics}/constants.d.ts +0 -0
- package/{metrics → dist/src/metrics}/constants.js +0 -0
- package/{metrics → dist/src/metrics}/index.d.ts +0 -0
- package/{package → dist/src}/metrics/index.js +0 -1
- package/dist/src/metrics/util.d.ts +7 -0
- package/{package → dist/src}/metrics/util.js +2 -2
- package/{adapter.d.ts → dist/src/package/adapter.d.ts} +2 -2
- package/{adapter.js → dist/src/package/adapter.js} +0 -0
- package/{background-executor.d.ts → dist/src/package/background-executor.d.ts} +0 -0
- package/{package → dist/src/package}/background-executor.js +0 -0
- package/{package → dist/src/package}/cache/factory.d.ts +0 -0
- package/{cache → dist/src/package/cache}/factory.js +0 -0
- package/{cache → dist/src/package/cache}/index.d.ts +0 -0
- package/{cache → dist/src/package/cache}/index.js +0 -0
- package/{package → dist/src/package}/cache/local.d.ts +0 -0
- package/{package → dist/src/package}/cache/local.js +0 -0
- package/{package → dist/src/package}/cache/metrics.d.ts +0 -0
- package/{package → dist/src/package}/cache/metrics.js +0 -0
- package/{package → dist/src/package}/cache/redis.d.ts +0 -0
- package/{cache → dist/src/package/cache}/redis.js +0 -0
- package/{config → dist/src/package/config}/index.d.ts +0 -0
- package/{config → dist/src/package/config}/index.js +0 -0
- package/{package → dist/src/package}/config/provider-limits.d.ts +0 -0
- package/{package → dist/src/package}/config/provider-limits.js +2 -1
- package/{examples → dist/src/package/examples}/coingecko/batch-warming.d.ts +0 -0
- package/{examples → dist/src/package/examples}/coingecko/batch-warming.js +0 -0
- package/{examples → dist/src/package/examples}/coingecko/index.d.ts +0 -0
- package/{examples → dist/src/package/examples}/coingecko/index.js +0 -0
- package/{examples → dist/src/package/examples}/coingecko/rest.d.ts +0 -0
- package/{examples → dist/src/package/examples}/coingecko/rest.js +0 -0
- package/{package → dist/src/package}/examples/ncfx/config/index.d.ts +0 -0
- package/{package → dist/src/package}/examples/ncfx/config/index.js +0 -0
- package/{examples → dist/src/package/examples}/ncfx/index.d.ts +0 -0
- package/{examples → dist/src/package/examples}/ncfx/index.js +0 -0
- package/{examples → dist/src/package/examples}/ncfx/websocket.d.ts +0 -0
- package/{examples → dist/src/package/examples}/ncfx/websocket.js +0 -0
- package/{index.d.ts → dist/src/package/index.d.ts} +1 -1
- package/{index.js → dist/src/package/index.js} +0 -0
- package/{package → dist/src/package}/metrics/constants.d.ts +0 -0
- package/{package → dist/src/package}/metrics/constants.js +0 -0
- package/{package → dist/src/package}/metrics/index.d.ts +0 -0
- package/{metrics → dist/src/package/metrics}/index.js +0 -0
- package/{metrics → dist/src/package/metrics}/util.d.ts +0 -0
- package/{metrics → dist/src/package/metrics}/util.js +0 -0
- package/dist/src/package/package.json +72 -0
- package/{package → dist/src/package}/rate-limiting/background/fixed-frequency.d.ts +0 -0
- package/{package → dist/src/package}/rate-limiting/background/fixed-frequency.js +0 -0
- package/{package → dist/src/package}/rate-limiting/index.d.ts +2 -2
- package/{package → dist/src/package}/rate-limiting/index.js +0 -0
- package/{package → dist/src/package}/rate-limiting/metrics.d.ts +0 -0
- package/{package → dist/src/package}/rate-limiting/metrics.js +0 -0
- package/{package → dist/src/package}/rate-limiting/request/simple-counting.d.ts +0 -0
- package/{package → dist/src/package}/rate-limiting/request/simple-counting.js +0 -0
- package/{package → dist/src/package}/test.d.ts +0 -0
- package/{package → dist/src/package}/test.js +0 -0
- package/{package → dist/src/package}/transports/batch-warming.d.ts +0 -0
- package/{package → dist/src/package}/transports/batch-warming.js +0 -0
- package/{package → dist/src/package}/transports/index.d.ts +0 -0
- package/{package → dist/src/package}/transports/index.js +0 -0
- package/{package → dist/src/package}/transports/metrics.d.ts +1 -1
- package/{package → dist/src/package}/transports/metrics.js +0 -0
- package/{package → dist/src/package}/transports/rest.d.ts +0 -0
- package/{package → dist/src/package}/transports/rest.js +0 -0
- package/{package → dist/src/package}/transports/util.d.ts +0 -0
- package/{package → dist/src/package}/transports/util.js +0 -0
- package/{package → dist/src/package}/transports/websocket.d.ts +0 -0
- package/{package → dist/src/package}/transports/websocket.js +0 -0
- package/{package → dist/src/package}/util/expiring-sorted-set.d.ts +0 -0
- package/{package → dist/src/package}/util/expiring-sorted-set.js +0 -0
- package/{package → dist/src/package}/util/index.d.ts +0 -0
- package/{package → dist/src/package}/util/index.js +0 -0
- package/{package → dist/src/package}/util/logger.d.ts +0 -0
- package/{package → dist/src/package}/util/logger.js +0 -0
- package/{package → dist/src/package}/util/request.d.ts +0 -0
- package/{package → dist/src/package}/util/request.js +0 -0
- package/{package → dist/src/package}/validation/error.d.ts +0 -0
- package/{package → dist/src/package}/validation/error.js +0 -0
- package/{package → dist/src/package}/validation/index.d.ts +0 -0
- package/{package → dist/src/package}/validation/index.js +0 -0
- package/{package → dist/src/package}/validation/input-params.d.ts +0 -0
- package/{package → dist/src/package}/validation/input-params.js +0 -0
- package/{package → dist/src/package}/validation/override-functions.d.ts +0 -0
- package/{package → dist/src/package}/validation/override-functions.js +0 -0
- package/{package → dist/src/package}/validation/preset-tokens.json +0 -0
- package/{package → dist/src/package}/validation/validator.d.ts +0 -0
- package/{package → dist/src/package}/validation/validator.js +0 -0
- package/{package → dist/src}/package.json +5 -2
- package/{rate-limiting → dist/src/rate-limiting}/background/fixed-frequency.d.ts +2 -1
- package/{rate-limiting → dist/src/rate-limiting}/background/fixed-frequency.js +0 -2
- package/{rate-limiting → dist/src/rate-limiting}/index.d.ts +4 -3
- package/{rate-limiting → dist/src/rate-limiting}/index.js +0 -0
- package/{rate-limiting → dist/src/rate-limiting}/metrics.d.ts +0 -0
- package/{rate-limiting → dist/src/rate-limiting}/metrics.js +0 -0
- package/{rate-limiting → dist/src/rate-limiting}/request/simple-counting.d.ts +2 -1
- package/{rate-limiting → dist/src/rate-limiting}/request/simple-counting.js +0 -0
- package/{test.d.ts → dist/src/test.d.ts} +0 -0
- package/{test.js → dist/src/test.js} +2 -2
- package/{transports → dist/src/transports}/batch-warming.d.ts +4 -3
- package/{transports → dist/src/transports}/batch-warming.js +4 -4
- package/{transports → dist/src/transports}/index.d.ts +5 -22
- package/{transports → dist/src/transports}/index.js +3 -3
- package/{transports → dist/src/transports}/metrics.d.ts +4 -3
- package/{transports → dist/src/transports}/metrics.js +2 -2
- package/{transports → dist/src/transports}/rest.d.ts +2 -1
- package/{transports → dist/src/transports}/rest.js +3 -1
- package/{transports → dist/src/transports}/util.d.ts +0 -0
- package/{transports → dist/src/transports}/util.js +0 -0
- package/{transports → dist/src/transports}/websocket.d.ts +7 -7
- package/{transports → dist/src/transports}/websocket.js +8 -11
- package/{util → dist/src/util}/expiring-sorted-set.d.ts +0 -0
- package/{util → dist/src/util}/expiring-sorted-set.js +0 -0
- package/{util → dist/src/util}/index.d.ts +2 -1
- package/{util → dist/src/util}/index.js +1 -1
- package/{util → dist/src/util}/logger.d.ts +0 -0
- package/{util → dist/src/util}/logger.js +0 -0
- package/{util → dist/src/util}/request.d.ts +5 -3
- package/{util → dist/src/util}/request.js +0 -0
- package/dist/src/util/subscription-set/expiring-sorted-set.d.ts +22 -0
- package/dist/src/util/subscription-set/expiring-sorted-set.js +47 -0
- package/dist/src/util/subscription-set/subscription-set.d.ts +18 -0
- package/dist/src/util/subscription-set/subscription-set.js +19 -0
- package/dist/src/util/test-payload-loader.d.ts +25 -0
- package/dist/src/util/test-payload-loader.js +83 -0
- package/{validation → dist/src/validation}/error.d.ts +4 -4
- package/{validation → dist/src/validation}/error.js +1 -1
- package/{validation → dist/src/validation}/index.d.ts +0 -0
- package/{validation → dist/src/validation}/index.js +8 -3
- package/{validation → dist/src/validation}/input-params.d.ts +0 -0
- package/{validation → dist/src/validation}/input-params.js +0 -0
- package/dist/src/validation/override-functions.d.ts +3 -0
- package/{validation → dist/src/validation}/override-functions.js +0 -0
- package/{validation → dist/src/validation}/preset-tokens.json +0 -0
- package/{validation → dist/src/validation}/validator.d.ts +0 -0
- package/{validation → dist/src/validation}/validator.js +0 -0
- package/docker-compose.yaml +35 -0
- package/env.sh +54 -0
- package/env2.sh +55 -0
- package/package.json +5 -3
- package/publish.sh +0 -0
- package/src/adapter.ts +263 -0
- package/src/background-executor.ts +52 -0
- package/src/cache/factory.ts +26 -0
- package/src/cache/index.ts +258 -0
- package/src/cache/local.ts +73 -0
- package/src/cache/metrics.ts +112 -0
- package/src/cache/redis.ts +93 -0
- package/src/config/index.ts +517 -0
- package/src/config/provider-limits.ts +130 -0
- package/src/examples/bank-frick/README.MD +10 -0
- package/src/examples/bank-frick/accounts.ts +246 -0
- package/src/examples/bank-frick/config/index.ts +53 -0
- package/src/examples/bank-frick/index.ts +13 -0
- package/src/examples/bank-frick/types.d.ts +38 -0
- package/src/examples/bank-frick/util.ts +55 -0
- package/src/examples/coingecko/batch-warming.ts +78 -0
- package/src/examples/coingecko/index.ts +9 -0
- package/src/examples/coingecko/rest.ts +77 -0
- package/src/examples/ncfx/config/index.ts +12 -0
- package/src/examples/ncfx/index.ts +9 -0
- package/src/examples/ncfx/websocket.ts +99 -0
- package/src/index.ts +149 -0
- package/src/metrics/constants.ts +23 -0
- package/src/metrics/index.ts +115 -0
- package/src/metrics/util.ts +18 -0
- package/src/rate-limiting/background/fixed-frequency.ts +45 -0
- package/src/rate-limiting/index.ts +100 -0
- package/src/rate-limiting/metrics.ts +18 -0
- package/src/rate-limiting/request/simple-counting.ts +76 -0
- package/src/test.ts +5 -0
- package/src/transports/batch-warming.ts +122 -0
- package/src/transports/index.ts +152 -0
- package/src/transports/metrics.ts +95 -0
- package/src/transports/rest.ts +164 -0
- package/src/transports/util.ts +63 -0
- package/src/transports/websocket.ts +245 -0
- package/src/util/index.ts +22 -0
- package/src/util/logger.ts +69 -0
- package/src/util/request.ts +117 -0
- package/src/util/subscription-set/expiring-sorted-set.ts +54 -0
- package/src/util/subscription-set/subscription-set.ts +35 -0
- package/src/util/test-payload-loader.ts +87 -0
- package/src/validation/error.ts +116 -0
- package/src/validation/index.ts +110 -0
- package/src/validation/input-params.ts +45 -0
- package/src/validation/override-functions.ts +44 -0
- package/src/validation/preset-tokens.json +23 -0
- package/src/validation/validator.ts +384 -0
- package/test/adapter.test.ts +27 -0
- package/test/background-executor.test.ts +108 -0
- package/test/cache/cache-key.test.ts +114 -0
- package/test/cache/helper.ts +100 -0
- package/test/cache/local.test.ts +54 -0
- package/test/cache/redis.test.ts +89 -0
- package/test/correlation.test.ts +114 -0
- package/test/index.test.ts +37 -0
- package/test/metrics/feed-id.test.ts +38 -0
- package/test/metrics/helper.ts +14 -0
- package/test/metrics/labels.test.ts +36 -0
- package/test/metrics/metrics.test.ts +267 -0
- package/test/metrics/redis-metrics.test.ts +113 -0
- package/test/metrics/warmer-metrics.test.ts +192 -0
- package/test/metrics/ws-metrics.test.ts +225 -0
- package/test/rate-limit-config.test.ts +242 -0
- package/test/smoke.test.ts +166 -0
- package/test/transports/batch.test.ts +465 -0
- package/test/transports/rest.test.ts +242 -0
- package/test/transports/websocket.test.ts +183 -0
- package/test/tsconfig.json +5 -0
- package/test/util.ts +77 -0
- package/test/validation.test.ts +178 -0
- package/test-payload-fail.json +3 -0
- package/test-payload.js +22 -0
- package/test-payload.json +7 -0
- package/test.sh +20 -0
- package/test2.sh +2 -0
- package/tsconfig.json +25 -0
- package/typedoc.json +6 -0
- package/webpack.config.js +23 -0
- package/chainlink-external-adapter-framework-v0.0.8.tgz +0 -0
- package/package/adapter.d.ts +0 -88
- package/package/adapter.js +0 -112
- package/package/examples/coingecko/batch-warming.d.ts +0 -2
- package/package/examples/coingecko/index.d.ts +0 -2
- package/package/examples/coingecko/rest.d.ts +0 -2
- package/package/examples/ncfx/index.d.ts +0 -2
- package/package/metrics/util.d.ts +0 -3
- package/validation/override-functions.d.ts +0 -3
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chainlink/external-adapter-framework",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"dependencies": {
|
|
@@ -37,7 +37,10 @@
|
|
|
37
37
|
"nock": "^13.2.4",
|
|
38
38
|
"pino-pretty": "^7.6.0",
|
|
39
39
|
"prettier": "^2.6.1",
|
|
40
|
-
"
|
|
40
|
+
"ts-loader": "^9.3.1",
|
|
41
|
+
"typedoc": "^0.22.15",
|
|
42
|
+
"webpack": "^5.74.0",
|
|
43
|
+
"webpack-cli": "^4.10.0"
|
|
41
44
|
},
|
|
42
45
|
"prettier": {
|
|
43
46
|
"semi": false,
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { AdapterRateLimitTier, BackgroundExecuteRateLimiter } from '..';
|
|
2
2
|
import { AdapterEndpoint } from '../../adapter';
|
|
3
|
+
import { SettingsMap } from '../../config';
|
|
3
4
|
export declare const DEFAULT_SHARED_MS_BETWEEN_REQUESTS = 5000;
|
|
4
5
|
export declare class FixedFrequencyRateLimiter implements BackgroundExecuteRateLimiter {
|
|
5
6
|
msBetweenRequestsMap: {
|
|
6
7
|
[endpointName: string]: number;
|
|
7
8
|
};
|
|
8
|
-
initialize(endpoints: AdapterEndpoint[], limits?: AdapterRateLimitTier): this;
|
|
9
|
+
initialize<Params, Result, CustomSettings extends SettingsMap>(endpoints: AdapterEndpoint<Params, Result, CustomSettings>[], limits?: AdapterRateLimitTier): this;
|
|
9
10
|
msUntilNextExecution(endpointName: string): number;
|
|
10
11
|
}
|
|
@@ -19,11 +19,9 @@ class FixedFrequencyRateLimiter {
|
|
|
19
19
|
}
|
|
20
20
|
logger.debug('Using fixed frequency batch rate limiting');
|
|
21
21
|
for (const endpoint of endpoints) {
|
|
22
|
-
// TODO: See if we can remove this runtime check
|
|
23
22
|
if (endpoint.rateLimiting?.allocationPercentage == null) {
|
|
24
23
|
throw new Error(`Allocation percentage for endpoint "${endpoint.name}" is null`);
|
|
25
24
|
}
|
|
26
|
-
// TODO: Implement different strategy where this is not fixed, but rather divided based on whether all warmers are active
|
|
27
25
|
this.msBetweenRequestsMap[endpoint.name] =
|
|
28
26
|
(sharedMsBetweenRequests / endpoint.rateLimiting?.allocationPercentage) * 100;
|
|
29
27
|
logger.debug(`Endpoint [${endpoint.name}]: ${this.msBetweenRequestsMap[endpoint.name] / 1000}s between requests`);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AdapterEndpoint } from '../adapter';
|
|
2
|
+
import { SettingsMap } from '../config';
|
|
2
3
|
export * from './request/simple-counting';
|
|
3
4
|
export * from './background/fixed-frequency';
|
|
4
5
|
export interface AdapterRateLimitTier {
|
|
@@ -17,7 +18,7 @@ export interface RateLimiter {
|
|
|
17
18
|
* @param limits - settings for how much throughput to allow for the Adapter
|
|
18
19
|
* @param endpoints - list of adapter endpoints
|
|
19
20
|
*/
|
|
20
|
-
initialize(endpoints: AdapterEndpoint[], limits: AdapterRateLimitTier): this;
|
|
21
|
+
initialize<Params, Result, CustomSettings extends SettingsMap>(endpoints: AdapterEndpoint<Params, Result, CustomSettings>[], limits: AdapterRateLimitTier): this;
|
|
21
22
|
}
|
|
22
23
|
/**
|
|
23
24
|
* RequestRateLimiters perform checks agains imminent outbound requests for any transport.
|
|
@@ -43,7 +44,7 @@ export interface BackgroundExecuteRateLimiter extends RateLimiter {
|
|
|
43
44
|
* @param limits - the rate limit tier set for the adapter
|
|
44
45
|
* @returns the most restrictive of the set options, in requests per second
|
|
45
46
|
*/
|
|
46
|
-
export declare const consolidateTierLimits: (limits?: AdapterRateLimitTier
|
|
47
|
+
export declare const consolidateTierLimits: (limits?: AdapterRateLimitTier) => number;
|
|
47
48
|
/**
|
|
48
49
|
* Validates rate limiting tiers specified for the adapter, and returns the one to use.
|
|
49
50
|
*
|
|
@@ -51,4 +52,4 @@ export declare const consolidateTierLimits: (limits?: AdapterRateLimitTier | und
|
|
|
51
52
|
* @param selectedTier - chosen API tier from settings, if present
|
|
52
53
|
* @returns the specified API tier, or a default one if none are specified
|
|
53
54
|
*/
|
|
54
|
-
export declare const getRateLimitingTier: (tiers?: Record<string, AdapterRateLimitTier
|
|
55
|
+
export declare const getRateLimitingTier: (tiers?: Record<string, AdapterRateLimitTier>, selectedTier?: string) => AdapterRateLimitTier | undefined;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AdapterRateLimitTier, RateLimiter } from '..';
|
|
2
2
|
import { AdapterEndpoint } from '../../adapter';
|
|
3
|
+
import { SettingsMap } from '../../config';
|
|
3
4
|
/**
|
|
4
5
|
* This rate limiter is the simplest stateful option.
|
|
5
6
|
* On startup, it'll compare the different thresholds for each tier, calculate them all
|
|
@@ -15,6 +16,6 @@ export declare class SimpleCountingRateLimiter implements RateLimiter {
|
|
|
15
16
|
requestsThisMinute: number;
|
|
16
17
|
perSecondLimit: number;
|
|
17
18
|
perMinuteLimit: number;
|
|
18
|
-
initialize(endpoints: AdapterEndpoint[], limits?: AdapterRateLimitTier): this;
|
|
19
|
+
initialize<Params, Result, CustomSettings extends SettingsMap>(endpoints: AdapterEndpoint<Params, Result, CustomSettings>[], limits?: AdapterRateLimitTier): this;
|
|
19
20
|
isUnderLimits(): boolean;
|
|
20
21
|
}
|
|
File without changes
|
|
File without changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const _1 = require(".");
|
|
4
|
-
const
|
|
4
|
+
const bank_frick_1 = require("./examples/bank-frick");
|
|
5
5
|
// Start sample adapter
|
|
6
|
-
(0, _1.expose)(
|
|
6
|
+
(0, _1.expose)(bank_frick_1.adapter);
|
|
@@ -2,9 +2,10 @@ import { AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
|
2
2
|
import { Cache } from '../cache';
|
|
3
3
|
import { AdapterConfig, SettingsMap } from '../config';
|
|
4
4
|
import { BackgroundExecuteRateLimiter } from '../rate-limiting';
|
|
5
|
-
import {
|
|
5
|
+
import { SubscriptionSet } from '../util';
|
|
6
6
|
import { AdapterRequest, ProviderResult } from '../util/request';
|
|
7
|
-
import {
|
|
7
|
+
import { Transport } from './';
|
|
8
|
+
import { AdapterContext, AdapterDependencies } from '../adapter';
|
|
8
9
|
/**
|
|
9
10
|
* Transport implementation that takes incoming batches requests and keeps a warm cache of values.
|
|
10
11
|
* Within the setup function, adapter params are added to an set that also keeps track and expires values.
|
|
@@ -21,7 +22,7 @@ export declare class BatchWarmingTransport<AdapterParams, ProviderRequestBody, P
|
|
|
21
22
|
private config;
|
|
22
23
|
cache: Cache;
|
|
23
24
|
rateLimiter: BackgroundExecuteRateLimiter;
|
|
24
|
-
|
|
25
|
+
subscriptionSet: SubscriptionSet<AdapterParams>;
|
|
25
26
|
WARMER_ACTIVE: boolean;
|
|
26
27
|
constructor(config: {
|
|
27
28
|
prepareRequest: (params: AdapterParams[], context: AdapterContext<CustomSettings>) => AxiosRequestConfig<ProviderRequestBody>;
|
|
@@ -46,7 +46,6 @@ const logger = (0, util_1.makeLogger)('BatchWarmingTransport');
|
|
|
46
46
|
class BatchWarmingTransport {
|
|
47
47
|
constructor(config) {
|
|
48
48
|
this.config = config;
|
|
49
|
-
this.expiringSortedSet = new util_1.ExpiringSortedSet(); // TODO: Move to dependencies, inject
|
|
50
49
|
// Flag used to track whether the warmer has moved from having no entries to having some and vice versa
|
|
51
50
|
// Used for recording the cache warmer active metrics accurately
|
|
52
51
|
this.WARMER_ACTIVE = false;
|
|
@@ -54,17 +53,18 @@ class BatchWarmingTransport {
|
|
|
54
53
|
async initialize(dependencies) {
|
|
55
54
|
this.cache = dependencies.cache;
|
|
56
55
|
this.rateLimiter = dependencies.backgroundExecuteRateLimiter;
|
|
56
|
+
this.subscriptionSet = dependencies.subscriptionSetFactory.buildSet();
|
|
57
57
|
}
|
|
58
58
|
async hasBeenSetUp(req) {
|
|
59
|
-
return !!this.
|
|
59
|
+
return !!(await this.subscriptionSet.get(req.requestContext.cacheKey));
|
|
60
60
|
}
|
|
61
61
|
async setup(req, config) {
|
|
62
62
|
logger.debug(`Adding entry to batch warming set: [${req.requestContext.cacheKey}] = ${req.requestContext.data}`);
|
|
63
|
-
this.
|
|
63
|
+
await this.subscriptionSet.add(req.requestContext.cacheKey, req.requestContext.data, config.WARMUP_SUBSCRIPTION_TTL);
|
|
64
64
|
}
|
|
65
65
|
async backgroundExecute(context) {
|
|
66
66
|
logger.debug('Starting background execute');
|
|
67
|
-
const entries = this.
|
|
67
|
+
const entries = await this.subscriptionSet.getAll();
|
|
68
68
|
if (!entries.length) {
|
|
69
69
|
logger.debug('No entries in batch warming set, skipping');
|
|
70
70
|
if (this.WARMER_ACTIVE) {
|
|
@@ -1,28 +1,11 @@
|
|
|
1
1
|
import { FastifyReply } from 'fastify';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { AdapterConfig,
|
|
5
|
-
import { BackgroundExecuteRateLimiter, RequestRateLimiter } from '../rate-limiting';
|
|
2
|
+
import { AdapterContext, AdapterDependencies, Adapter } from '../adapter';
|
|
3
|
+
import { CacheEntry } from '../cache';
|
|
4
|
+
import { AdapterConfig, SettingsMap } from '../config';
|
|
6
5
|
import { AdapterRequest, AdapterResponse, ProviderResult } from '../util/request';
|
|
7
6
|
export * from './batch-warming';
|
|
8
7
|
export * from './rest';
|
|
9
8
|
export * from './websocket';
|
|
10
|
-
/**
|
|
11
|
-
* Dependencies that will be injected into the Adapter on startup
|
|
12
|
-
*/
|
|
13
|
-
export interface AdapterDependencies {
|
|
14
|
-
cache: Cache;
|
|
15
|
-
requestRateLimiter: RequestRateLimiter;
|
|
16
|
-
backgroundExecuteRateLimiter: BackgroundExecuteRateLimiter;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Context that will be used on background executions of a Transport.
|
|
20
|
-
* For example, the endpointName used to log statements or generate Cache keys.
|
|
21
|
-
*/
|
|
22
|
-
export interface AdapterContext<CustomSettings extends CustomSettingsType<CustomSettings> = SettingsMap> {
|
|
23
|
-
adapterEndpoint: AdapterEndpoint;
|
|
24
|
-
adapterConfig: AdapterConfig<CustomSettings>;
|
|
25
|
-
}
|
|
26
9
|
/**
|
|
27
10
|
* Generic interface for a Transport.
|
|
28
11
|
* A Transport defines the way in which an AdapterEndpoint will process incoming requests to
|
|
@@ -76,7 +59,7 @@ export interface Transport<Params, Result, CustomSettings extends SettingsMap> {
|
|
|
76
59
|
* @param context - context for the Adapter
|
|
77
60
|
* @returns a list of CacheEntries of AdapterResponses
|
|
78
61
|
*/
|
|
79
|
-
export declare const buildCacheEntriesFromResults: <Params,
|
|
62
|
+
export declare const buildCacheEntriesFromResults: <Params, CustomSettings extends SettingsMap>(results: ProviderResult<Params>[], context: AdapterContext<CustomSettings>) => CacheEntry<AdapterResponse<null>>[];
|
|
80
63
|
/**
|
|
81
64
|
* Takes an Adapter, its configuration, and its dependencies, and it creates an express middleware
|
|
82
65
|
* that will pass along the AdapterRequest to the appropriate Transport (acc. to the endpoint in the req.)
|
|
@@ -84,4 +67,4 @@ export declare const buildCacheEntriesFromResults: <Params, Context extends Adap
|
|
|
84
67
|
* @param adapter - main adapter object, already initialized
|
|
85
68
|
* @returns the transport handler middleware function
|
|
86
69
|
*/
|
|
87
|
-
export declare const buildTransportHandler: (adapter:
|
|
70
|
+
export declare const buildTransportHandler: (adapter: Adapter) => (req: AdapterRequest, reply: FastifyReply) => Promise<never>;
|
|
@@ -43,9 +43,9 @@ const buildCacheEntriesFromResults = (results, context) => results.map((r) => {
|
|
|
43
43
|
maxAge: Date.now() + context.adapterConfig.CACHE_MAX_AGE,
|
|
44
44
|
meta: {
|
|
45
45
|
metrics: {
|
|
46
|
-
feedId: (0, cache_1.calculateFeedId)(context
|
|
47
|
-
}
|
|
48
|
-
}
|
|
46
|
+
feedId: (0, cache_1.calculateFeedId)(context, r.params),
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
49
|
};
|
|
50
50
|
cacheEntry.value = { ...cacheEntry.value, ...metrics };
|
|
51
51
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as client from 'prom-client';
|
|
2
|
-
import { AdapterContext } from '
|
|
3
|
-
|
|
2
|
+
import { AdapterContext } from '../adapter';
|
|
3
|
+
import { SettingsMap } from '../config';
|
|
4
|
+
export declare const dataProviderMetricsLabel: (providerStatusCode?: number, method?: string) => {
|
|
4
5
|
provider_status_code: number | undefined;
|
|
5
6
|
method: string;
|
|
6
7
|
};
|
|
@@ -13,7 +14,7 @@ export declare const messageSubsLabels: (feed_id: string, cache_key: string) =>
|
|
|
13
14
|
feed_id: string;
|
|
14
15
|
subscription_key: string;
|
|
15
16
|
};
|
|
16
|
-
export declare const recordWsMessageMetrics: <AdapterParams>(context: AdapterContext
|
|
17
|
+
export declare const recordWsMessageMetrics: <AdapterParams, CustomSettings extends SettingsMap>(context: AdapterContext<CustomSettings>, subscribes: AdapterParams[], unsubscrices: AdapterParams[]) => void;
|
|
17
18
|
export declare const wsConnectionActive: client.Gauge<"url">;
|
|
18
19
|
export declare const wsConnectionErrors: client.Counter<"message" | "url">;
|
|
19
20
|
export declare const wsSubscriptionActive: client.Gauge<"feed_id" | "connection_url" | "subscription_key">;
|
|
@@ -59,7 +59,7 @@ exports.messageSubsLabels = messageSubsLabels;
|
|
|
59
59
|
// since avoiding storing extra info in expiring sorted set
|
|
60
60
|
const recordWsMessageMetrics = (context, subscribes, unsubscrices) => {
|
|
61
61
|
subscribes.forEach((param) => {
|
|
62
|
-
const feedId = (0, cache_1.calculateFeedId)(context
|
|
62
|
+
const feedId = (0, cache_1.calculateFeedId)(context, param);
|
|
63
63
|
const cacheKey = (0, cache_1.calculateCacheKey)(context, param);
|
|
64
64
|
// Record total number of ws messages sent
|
|
65
65
|
exports.wsMessageTotal.labels((0, exports.messageSubsLabels)(feedId, cacheKey)).inc();
|
|
@@ -69,7 +69,7 @@ const recordWsMessageMetrics = (context, subscribes, unsubscrices) => {
|
|
|
69
69
|
exports.wsSubscriptionActive.labels((0, exports.messageSubsLabels)(feedId, cacheKey)).inc();
|
|
70
70
|
});
|
|
71
71
|
unsubscrices.forEach((param) => {
|
|
72
|
-
const feedId = (0, cache_1.calculateFeedId)(context
|
|
72
|
+
const feedId = (0, cache_1.calculateFeedId)(context, param);
|
|
73
73
|
const cacheKey = (0, cache_1.calculateCacheKey)(context, param);
|
|
74
74
|
// Record total number of ws messages sent
|
|
75
75
|
exports.wsMessageTotal.labels((0, exports.messageSubsLabels)(feedId, cacheKey)).inc();
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { AdapterRequest, AdapterResponse } from '../util/request';
|
|
2
|
-
import {
|
|
2
|
+
import { Transport } from './';
|
|
3
3
|
import { Cache } from '../cache';
|
|
4
4
|
import { AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
5
5
|
import { AdapterConfig, SettingsMap } from '../config';
|
|
6
6
|
import { RequestRateLimiter } from '../rate-limiting';
|
|
7
|
+
import { AdapterDependencies } from '../adapter';
|
|
7
8
|
/**
|
|
8
9
|
* Transport implementation that takes incoming requests, transforms them into a DataProvider request,
|
|
9
10
|
* and executes that request returning the response immediately from the `setup` function.
|
|
@@ -101,7 +101,9 @@ class RestTransport {
|
|
|
101
101
|
if (config.METRICS_ENABLED && config.EXPERIMENTAL_METRICS_ENABLED) {
|
|
102
102
|
// TODO: Potentially create function to add all telemetry data
|
|
103
103
|
parsedResponse.maxAge = Date.now() + config.CACHE_MAX_AGE;
|
|
104
|
-
parsedResponse.meta = {
|
|
104
|
+
parsedResponse.meta = {
|
|
105
|
+
metrics: { feedId: req.requestContext.meta?.metrics?.feedId || 'N/A' },
|
|
106
|
+
};
|
|
105
107
|
}
|
|
106
108
|
logger.debug('Setting provider response in cache');
|
|
107
109
|
await this.cache.set(req.requestContext.cacheKey, parsedResponse, config.CACHE_MAX_AGE);
|
|
File without changes
|
|
File without changes
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import WebSocket from 'ws';
|
|
2
|
+
import { AdapterContext, AdapterDependencies } from '../adapter';
|
|
2
3
|
import { Cache } from '../cache';
|
|
3
|
-
import { SettingsMap } from '../config';
|
|
4
|
+
import { AdapterConfig, SettingsMap } from '../config';
|
|
4
5
|
import { BackgroundExecuteRateLimiter } from '../rate-limiting';
|
|
5
|
-
import {
|
|
6
|
+
import { SubscriptionSet } from '../util';
|
|
6
7
|
import { AdapterRequest, ProviderResult } from '../util/request';
|
|
7
|
-
import {
|
|
8
|
-
export declare const DEFAULT_WS_TTL = 10000;
|
|
8
|
+
import { Transport } from './';
|
|
9
9
|
declare type WebSocketClass = new (url: string, protocols?: string | string[] | undefined) => WebSocket;
|
|
10
10
|
export declare class WebSocketClassProvider {
|
|
11
11
|
static ctor: WebSocketClass;
|
|
@@ -55,7 +55,7 @@ export interface WebSocketTransportConfig<AdapterParams, ProviderDataMessage, Cu
|
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
58
|
-
* Transport implementation that takes incoming requests, adds them to an [[
|
|
58
|
+
* Transport implementation that takes incoming requests, adds them to an [[subscriptionSet]] and,
|
|
59
59
|
* through a WebSocket connection, subscribes to the relevant feeds to populate the cache.
|
|
60
60
|
*
|
|
61
61
|
* @typeParam AdapterParams - interface for the adapter request body
|
|
@@ -65,13 +65,13 @@ export declare class WebSocketTransport<AdapterParams, ProviderDataMessage, Cust
|
|
|
65
65
|
private config;
|
|
66
66
|
cache: Cache;
|
|
67
67
|
rateLimiter: BackgroundExecuteRateLimiter;
|
|
68
|
-
|
|
68
|
+
subscriptionSet: SubscriptionSet<AdapterParams>;
|
|
69
69
|
localSubscriptions: AdapterParams[];
|
|
70
70
|
wsConnection: WebSocket;
|
|
71
71
|
constructor(config: WebSocketTransportConfig<AdapterParams, ProviderDataMessage, CustomSettings>);
|
|
72
72
|
initialize(dependencies: AdapterDependencies): Promise<void>;
|
|
73
73
|
hasBeenSetUp(req: AdapterRequest<AdapterParams>): Promise<boolean>;
|
|
74
|
-
setup(req: AdapterRequest<AdapterParams>): Promise<void>;
|
|
74
|
+
setup(req: AdapterRequest<AdapterParams>, config: AdapterConfig<CustomSettings>): Promise<void>;
|
|
75
75
|
serializeMessage(payload: unknown): string;
|
|
76
76
|
deserializeMessage(data: WebSocket.Data): ProviderDataMessage;
|
|
77
77
|
establishWsConnection(context: AdapterContext<CustomSettings>): Promise<unknown>;
|
|
@@ -26,13 +26,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.WebSocketTransport = exports.WebSocketClassProvider =
|
|
29
|
+
exports.WebSocketTransport = exports.WebSocketClassProvider = void 0;
|
|
30
30
|
const ws_1 = __importDefault(require("ws"));
|
|
31
31
|
const util_1 = require("../util");
|
|
32
32
|
const _1 = require("./");
|
|
33
33
|
const transportMetrics = __importStar(require("./metrics"));
|
|
34
|
-
// TODO: Config
|
|
35
|
-
exports.DEFAULT_WS_TTL = 10000;
|
|
36
34
|
const logger = (0, util_1.makeLogger)('WebSocketTransport');
|
|
37
35
|
class WebSocketClassProvider {
|
|
38
36
|
static set(ctor) {
|
|
@@ -45,7 +43,7 @@ class WebSocketClassProvider {
|
|
|
45
43
|
exports.WebSocketClassProvider = WebSocketClassProvider;
|
|
46
44
|
WebSocketClassProvider.ctor = ws_1.default;
|
|
47
45
|
/**
|
|
48
|
-
* Transport implementation that takes incoming requests, adds them to an [[
|
|
46
|
+
* Transport implementation that takes incoming requests, adds them to an [[subscriptionSet]] and,
|
|
49
47
|
* through a WebSocket connection, subscribes to the relevant feeds to populate the cache.
|
|
50
48
|
*
|
|
51
49
|
* @typeParam AdapterParams - interface for the adapter request body
|
|
@@ -55,21 +53,20 @@ class WebSocketTransport {
|
|
|
55
53
|
constructor(config) {
|
|
56
54
|
this.config = config;
|
|
57
55
|
// The double sets serve to create a simple polling mechanism instead of needing a subscription
|
|
58
|
-
// This one would be either local, redis, etc
|
|
59
|
-
this.expiringSortedSet = new util_1.ExpiringSortedSet(); // TODO: Move to dependencies, inject
|
|
60
56
|
// This one would not; this is always local state
|
|
61
57
|
this.localSubscriptions = [];
|
|
62
58
|
}
|
|
63
59
|
async initialize(dependencies) {
|
|
64
60
|
this.cache = dependencies.cache;
|
|
65
61
|
this.rateLimiter = dependencies.backgroundExecuteRateLimiter;
|
|
62
|
+
this.subscriptionSet = dependencies.subscriptionSetFactory.buildSet();
|
|
66
63
|
}
|
|
67
64
|
async hasBeenSetUp(req) {
|
|
68
|
-
return !!this.
|
|
65
|
+
return !!(await this.subscriptionSet.get(req.requestContext.cacheKey));
|
|
69
66
|
}
|
|
70
|
-
async setup(req) {
|
|
67
|
+
async setup(req, config) {
|
|
71
68
|
logger.debug(`Adding entry to subscription set: [${req.requestContext.cacheKey}] = ${req.requestContext.data}`);
|
|
72
|
-
this.
|
|
69
|
+
await this.subscriptionSet.add(req.requestContext.cacheKey, req.requestContext.data, config.WS_SUBSCRIPTION_TTL);
|
|
73
70
|
}
|
|
74
71
|
// TODO: Maybe we don't do this, and leave the preparation on the adapter's side?
|
|
75
72
|
// TODO: Maybe we store adapter params pre-prepared? That would be more efficient
|
|
@@ -85,7 +82,7 @@ class WebSocketTransport {
|
|
|
85
82
|
const ctor = WebSocketClassProvider.get();
|
|
86
83
|
this.wsConnection = new ctor(this.config.url);
|
|
87
84
|
this.wsConnection.addEventListener('open', async (event) => {
|
|
88
|
-
logger.debug(`Opened websocket connection
|
|
85
|
+
logger.debug(`Opened websocket connection. (event type ${event.type})`);
|
|
89
86
|
await this.config.handlers.open(this.wsConnection, context);
|
|
90
87
|
logger.debug('Successfully executed connection opened handler');
|
|
91
88
|
// Record active ws connections by incrementing count on open
|
|
@@ -121,7 +118,7 @@ class WebSocketTransport {
|
|
|
121
118
|
// Unlike cache warming, this execute will manage subscriptions
|
|
122
119
|
async backgroundExecute(context) {
|
|
123
120
|
logger.debug('Starting background execute, getting subscriptions from sorted set');
|
|
124
|
-
const desiredSubs = this.
|
|
121
|
+
const desiredSubs = await this.subscriptionSet.getAll();
|
|
125
122
|
logger.debug('Generating delta (subscribes & unsubscribes)');
|
|
126
123
|
// TODO: More efficient algorithm, this is really easy to read, but high(er) time complexity
|
|
127
124
|
const subscribeParams = desiredSubs.filter((s) => !this.localSubscriptions.includes(s));
|
|
File without changes
|
|
File without changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from './request';
|
|
2
2
|
export * from './logger';
|
|
3
|
-
export * from './
|
|
3
|
+
export * from './subscription-set/subscription-set';
|
|
4
4
|
/**
|
|
5
5
|
* Sleeps for the provided number of milliseconds
|
|
6
6
|
* @param ms - The number of milliseconds to sleep for
|
|
@@ -9,3 +9,4 @@ export * from './expiring-sorted-set';
|
|
|
9
9
|
export declare const sleep: (ms: number) => Promise<void>;
|
|
10
10
|
export declare const isObject: (o: unknown) => boolean;
|
|
11
11
|
export declare const isArray: (o: unknown) => boolean;
|
|
12
|
+
export declare type PromiseOrValue<T> = Promise<T> | T;
|
|
@@ -17,7 +17,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
exports.isArray = exports.isObject = exports.sleep = void 0;
|
|
18
18
|
__exportStar(require("./request"), exports);
|
|
19
19
|
__exportStar(require("./logger"), exports);
|
|
20
|
-
__exportStar(require("./
|
|
20
|
+
__exportStar(require("./subscription-set/subscription-set"), exports);
|
|
21
21
|
/**
|
|
22
22
|
* Sleeps for the provided number of milliseconds
|
|
23
23
|
* @param ms - The number of milliseconds to sleep for
|
|
File without changes
|
|
File without changes
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FastifyReply, FastifyRequest, HookHandlerDoneFunction } from 'fastify';
|
|
2
|
-
import {
|
|
2
|
+
import { Adapter } from '../adapter';
|
|
3
3
|
import { AdapterError } from '../validation/error';
|
|
4
4
|
declare module 'fastify' {
|
|
5
5
|
interface FastifyRequest {
|
|
@@ -38,7 +38,9 @@ export interface AdapterMetricsMeta {
|
|
|
38
38
|
feedId?: string;
|
|
39
39
|
cacheHit?: boolean;
|
|
40
40
|
}
|
|
41
|
-
export declare type AdapterRequestData = Record<string, unknown
|
|
41
|
+
export declare type AdapterRequestData = Record<string, unknown> & {
|
|
42
|
+
endpoint?: string;
|
|
43
|
+
};
|
|
42
44
|
export interface ProviderResult<Params> {
|
|
43
45
|
params: Params;
|
|
44
46
|
value: unknown;
|
|
@@ -52,4 +54,4 @@ export declare type AdapterResponse<T = unknown> = {
|
|
|
52
54
|
providerStatusCode?: number;
|
|
53
55
|
};
|
|
54
56
|
export declare type Middleware = ((req: AdapterRequest, reply: FastifyReply, done: HookHandlerDoneFunction) => FastifyReply | void) | ((req: AdapterRequest, reply: FastifyReply) => Promise<FastifyReply | void>);
|
|
55
|
-
export declare type AdapterMiddlewareBuilder = (adapter:
|
|
57
|
+
export declare type AdapterMiddlewareBuilder = (adapter: Adapter) => Middleware;
|
|
File without changes
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { SubscriptionSet } from './subscription-set';
|
|
2
|
+
/**
|
|
3
|
+
* An object describing an entry in the expiring sorted set.
|
|
4
|
+
* @typeParam T - the type of the entry's value
|
|
5
|
+
*/
|
|
6
|
+
interface ExpiringSortedSetEntry<T> {
|
|
7
|
+
value: T;
|
|
8
|
+
expirationTimestamp: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* This class implements a set of unique items, each of which has an expiration timestamp.
|
|
12
|
+
* On reads, items that have expired will be deleted from the set and not returned.
|
|
13
|
+
*
|
|
14
|
+
* @typeParam T - the type of the set entries' values
|
|
15
|
+
*/
|
|
16
|
+
export declare class ExpiringSortedSet<T> implements SubscriptionSet<T> {
|
|
17
|
+
map: Map<string, ExpiringSortedSetEntry<T>>;
|
|
18
|
+
add(key: string, value: T, ttl: number): void;
|
|
19
|
+
get(key: string): T | undefined;
|
|
20
|
+
getAll(): T[];
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ExpiringSortedSet = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* This class implements a set of unique items, each of which has an expiration timestamp.
|
|
6
|
+
* On reads, items that have expired will be deleted from the set and not returned.
|
|
7
|
+
*
|
|
8
|
+
* @typeParam T - the type of the set entries' values
|
|
9
|
+
*/
|
|
10
|
+
class ExpiringSortedSet {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.map = new Map();
|
|
13
|
+
}
|
|
14
|
+
add(key, value, ttl) {
|
|
15
|
+
this.map.set(key, {
|
|
16
|
+
value,
|
|
17
|
+
expirationTimestamp: Date.now() + ttl,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
get(key) {
|
|
21
|
+
const entry = this.map.get(key);
|
|
22
|
+
if (!entry) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
else if (entry.expirationTimestamp < Date.now()) {
|
|
26
|
+
return entry.value;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
this.map.delete(key);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
getAll() {
|
|
33
|
+
const results = [];
|
|
34
|
+
const now = Date.now();
|
|
35
|
+
// Since we're iterating, might as well prune here
|
|
36
|
+
for (const [key, entry] of this.map.entries()) {
|
|
37
|
+
if (entry.expirationTimestamp < now) {
|
|
38
|
+
this.map.delete(key); // In theory, this shouldn't happen frequently for feeds
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
results.push(entry.value);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return results;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.ExpiringSortedSet = ExpiringSortedSet;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { PromiseOrValue } from '..';
|
|
2
|
+
import { AdapterConfig } from '../../config';
|
|
3
|
+
/**
|
|
4
|
+
* Set to hold items to subscribe to from a provider (regardless of protocol)
|
|
5
|
+
*/
|
|
6
|
+
export interface SubscriptionSet<T> {
|
|
7
|
+
/** Add a new subscription to the set */
|
|
8
|
+
add(key: string, value: T, ttl: number): PromiseOrValue<void>;
|
|
9
|
+
/** Get a specific subscription from the set */
|
|
10
|
+
get(key: string): PromiseOrValue<T | undefined>;
|
|
11
|
+
/** Get all subscriptions from the set as a list */
|
|
12
|
+
getAll(): PromiseOrValue<T[]>;
|
|
13
|
+
}
|
|
14
|
+
export declare class SubscriptionSetFactory {
|
|
15
|
+
private cacheType;
|
|
16
|
+
constructor(config: AdapterConfig);
|
|
17
|
+
buildSet<T>(): SubscriptionSet<T>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SubscriptionSetFactory = void 0;
|
|
4
|
+
const expiring_sorted_set_1 = require("./expiring-sorted-set");
|
|
5
|
+
class SubscriptionSetFactory {
|
|
6
|
+
constructor(config) {
|
|
7
|
+
this.cacheType = config.CACHE_TYPE;
|
|
8
|
+
}
|
|
9
|
+
buildSet() {
|
|
10
|
+
switch (this.cacheType) {
|
|
11
|
+
case 'local':
|
|
12
|
+
return new expiring_sorted_set_1.ExpiringSortedSet();
|
|
13
|
+
case 'redis':
|
|
14
|
+
// TODO: Implement redis set
|
|
15
|
+
return new expiring_sorted_set_1.ExpiringSortedSet();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.SubscriptionSetFactory = SubscriptionSetFactory;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { AdapterRequestData } from './request';
|
|
2
|
+
/**
|
|
3
|
+
* The test payload read in from filesystem
|
|
4
|
+
*/
|
|
5
|
+
export interface Payload {
|
|
6
|
+
requests: Array<AdapterRequestData>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Test payload with discriminated union so we can tell when we should just do
|
|
10
|
+
* a simple liveness check rather than a sample request
|
|
11
|
+
*/
|
|
12
|
+
declare type TestPayload = (Payload & {
|
|
13
|
+
isDefault: false;
|
|
14
|
+
}) | {
|
|
15
|
+
isDefault: true;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Load in a JSON file containing a test payload for the current adapter,
|
|
19
|
+
* used in healthchecks to make sample requests
|
|
20
|
+
*
|
|
21
|
+
* @param fileName - name of file that contains the test payload data for the smoke endpoint
|
|
22
|
+
* @returns the parsed payload with individual requests
|
|
23
|
+
*/
|
|
24
|
+
export declare function loadTestPayload(fileName?: string): TestPayload;
|
|
25
|
+
export {};
|