@chainlink/external-adapter-framework 0.0.6 → 0.0.8
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/adapter.d.ts +88 -0
- package/adapter.js +112 -0
- package/background-executor.d.ts +11 -0
- package/background-executor.js +45 -0
- package/cache/factory.d.ts +6 -0
- package/cache/factory.js +57 -0
- package/cache/index.d.ts +90 -0
- package/cache/index.js +169 -0
- package/cache/local.d.ts +23 -0
- package/cache/local.js +83 -0
- package/cache/metrics.d.ts +27 -0
- package/cache/metrics.js +120 -0
- package/cache/redis.d.ts +16 -0
- package/cache/redis.js +100 -0
- package/chainlink-external-adapter-framework-v0.0.8.tgz +0 -0
- package/config/index.d.ts +195 -0
- package/config/index.js +365 -0
- package/config/provider-limits.d.ts +31 -0
- package/config/provider-limits.js +75 -0
- package/examples/coingecko/batch-warming.d.ts +2 -0
- package/examples/coingecko/batch-warming.js +52 -0
- package/examples/coingecko/index.d.ts +2 -0
- package/examples/coingecko/index.js +10 -0
- package/examples/coingecko/rest.d.ts +2 -0
- package/examples/coingecko/rest.js +50 -0
- package/examples/ncfx/config/index.d.ts +12 -0
- package/examples/ncfx/config/index.js +15 -0
- package/examples/ncfx/index.d.ts +2 -0
- package/examples/ncfx/index.js +10 -0
- package/examples/ncfx/websocket.d.ts +36 -0
- package/examples/ncfx/websocket.js +72 -0
- package/index.d.ts +12 -0
- package/index.js +92 -0
- package/metrics/constants.d.ts +16 -0
- package/metrics/constants.js +25 -0
- package/metrics/index.d.ts +15 -0
- package/metrics/index.js +123 -0
- package/metrics/util.d.ts +3 -0
- package/metrics/util.js +9 -0
- package/package/adapter.d.ts +88 -0
- package/package/adapter.js +112 -0
- package/package/background-executor.d.ts +11 -0
- package/package/background-executor.js +45 -0
- package/package/cache/factory.d.ts +6 -0
- package/package/cache/factory.js +57 -0
- package/package/cache/index.d.ts +90 -0
- package/package/cache/index.js +169 -0
- package/package/cache/local.d.ts +23 -0
- package/package/cache/local.js +83 -0
- package/package/cache/metrics.d.ts +27 -0
- package/package/cache/metrics.js +120 -0
- package/package/cache/redis.d.ts +16 -0
- package/package/cache/redis.js +100 -0
- package/package/config/index.d.ts +195 -0
- package/package/config/index.js +365 -0
- package/package/config/provider-limits.d.ts +31 -0
- package/package/config/provider-limits.js +75 -0
- package/package/examples/coingecko/batch-warming.d.ts +2 -0
- package/package/examples/coingecko/batch-warming.js +52 -0
- package/package/examples/coingecko/index.d.ts +2 -0
- package/package/examples/coingecko/index.js +10 -0
- package/package/examples/coingecko/rest.d.ts +2 -0
- package/package/examples/coingecko/rest.js +50 -0
- package/package/examples/ncfx/config/index.d.ts +12 -0
- package/package/examples/ncfx/config/index.js +15 -0
- package/package/examples/ncfx/index.d.ts +2 -0
- package/package/examples/ncfx/index.js +10 -0
- package/package/examples/ncfx/websocket.d.ts +36 -0
- package/package/examples/ncfx/websocket.js +72 -0
- package/package/index.d.ts +12 -0
- package/package/index.js +92 -0
- package/package/metrics/constants.d.ts +16 -0
- package/package/metrics/constants.js +25 -0
- package/package/metrics/index.d.ts +15 -0
- package/package/metrics/index.js +123 -0
- package/package/metrics/util.d.ts +3 -0
- package/package/metrics/util.js +9 -0
- package/package/package.json +69 -0
- package/package/rate-limiting/background/fixed-frequency.d.ts +10 -0
- package/package/rate-limiting/background/fixed-frequency.js +37 -0
- package/package/rate-limiting/index.d.ts +54 -0
- package/package/rate-limiting/index.js +63 -0
- package/package/rate-limiting/metrics.d.ts +3 -0
- package/package/rate-limiting/metrics.js +44 -0
- package/package/rate-limiting/request/simple-counting.d.ts +20 -0
- package/package/rate-limiting/request/simple-counting.js +62 -0
- package/package/test.d.ts +1 -0
- package/package/test.js +6 -0
- package/package/transports/batch-warming.d.ts +34 -0
- package/package/transports/batch-warming.js +101 -0
- package/package/transports/index.d.ts +87 -0
- package/package/transports/index.js +87 -0
- package/package/transports/metrics.d.ts +21 -0
- package/package/transports/metrics.js +105 -0
- package/package/transports/rest.d.ts +43 -0
- package/package/transports/rest.js +129 -0
- package/package/transports/util.d.ts +8 -0
- package/package/transports/util.js +85 -0
- package/package/transports/websocket.d.ts +80 -0
- package/package/transports/websocket.js +169 -0
- package/package/util/expiring-sorted-set.d.ts +21 -0
- package/package/util/expiring-sorted-set.js +47 -0
- package/package/util/index.d.ts +11 -0
- package/package/util/index.js +35 -0
- package/package/util/logger.d.ts +42 -0
- package/package/util/logger.js +62 -0
- package/package/util/request.d.ts +55 -0
- package/package/util/request.js +2 -0
- package/package/validation/error.d.ts +50 -0
- package/package/validation/error.js +79 -0
- package/package/validation/index.d.ts +5 -0
- package/package/validation/index.js +86 -0
- package/package/validation/input-params.d.ts +15 -0
- package/package/validation/input-params.js +30 -0
- package/package/validation/override-functions.d.ts +3 -0
- package/package/validation/override-functions.js +40 -0
- package/package/validation/preset-tokens.json +23 -0
- package/package/validation/validator.d.ts +47 -0
- package/package/validation/validator.js +303 -0
- package/package.json +1 -1
- package/rate-limiting/background/fixed-frequency.d.ts +10 -0
- package/rate-limiting/background/fixed-frequency.js +37 -0
- package/rate-limiting/index.d.ts +54 -0
- package/rate-limiting/index.js +63 -0
- package/rate-limiting/metrics.d.ts +3 -0
- package/rate-limiting/metrics.js +44 -0
- package/rate-limiting/request/simple-counting.d.ts +20 -0
- package/rate-limiting/request/simple-counting.js +62 -0
- package/test.d.ts +1 -0
- package/test.js +6 -0
- package/transports/batch-warming.d.ts +34 -0
- package/transports/batch-warming.js +101 -0
- package/transports/index.d.ts +87 -0
- package/transports/index.js +87 -0
- package/transports/metrics.d.ts +21 -0
- package/transports/metrics.js +105 -0
- package/transports/rest.d.ts +43 -0
- package/transports/rest.js +129 -0
- package/transports/util.d.ts +8 -0
- package/transports/util.js +85 -0
- package/transports/websocket.d.ts +80 -0
- package/transports/websocket.js +169 -0
- package/util/expiring-sorted-set.d.ts +21 -0
- package/util/expiring-sorted-set.js +47 -0
- package/util/index.d.ts +11 -0
- package/util/index.js +35 -0
- package/util/logger.d.ts +42 -0
- package/util/logger.js +62 -0
- package/util/request.d.ts +55 -0
- package/util/request.js +2 -0
- package/validation/error.d.ts +50 -0
- package/validation/error.js +79 -0
- package/validation/index.d.ts +5 -0
- package/validation/index.js +86 -0
- package/validation/input-params.d.ts +15 -0
- package/validation/input-params.js +30 -0
- package/validation/override-functions.d.ts +3 -0
- package/validation/override-functions.js +40 -0
- package/validation/preset-tokens.json +23 -0
- package/validation/validator.d.ts +47 -0
- package/validation/validator.js +303 -0
- package/.c8rc.json +0 -3
- package/.eslintignore +0 -9
- package/.eslintrc.js +0 -96
- package/.github/README.MD +0 -17
- package/.github/actions/setup/action.yaml +0 -13
- package/.github/workflows/main.yaml +0 -39
- package/.github/workflows/publish.yaml +0 -17
- package/.prettierignore +0 -13
- package/.yarnrc +0 -0
- package/README.md +0 -103
- package/docker-compose.yaml +0 -35
- package/src/adapter.ts +0 -236
- package/src/background-executor.ts +0 -53
- package/src/cache/factory.ts +0 -28
- package/src/cache/index.ts +0 -236
- package/src/cache/local.ts +0 -73
- package/src/cache/metrics.ts +0 -112
- package/src/cache/redis.ts +0 -93
- package/src/config/index.ts +0 -501
- package/src/config/provider-limits.ts +0 -130
- package/src/examples/coingecko/batch-warming.ts +0 -79
- package/src/examples/coingecko/index.ts +0 -9
- package/src/examples/coingecko/rest.ts +0 -77
- package/src/examples/ncfx/config/index.ts +0 -12
- package/src/examples/ncfx/index.ts +0 -9
- package/src/examples/ncfx/websocket.ts +0 -100
- package/src/index.ts +0 -106
- package/src/metrics/constants.ts +0 -23
- package/src/metrics/index.ts +0 -116
- package/src/metrics/util.ts +0 -11
- package/src/rate-limiting/background/fixed-frequency.ts +0 -47
- package/src/rate-limiting/index.ts +0 -100
- package/src/rate-limiting/metrics.ts +0 -18
- package/src/rate-limiting/request/simple-counting.ts +0 -76
- package/src/test.ts +0 -5
- package/src/transports/batch-warming.ts +0 -121
- package/src/transports/index.ts +0 -173
- package/src/transports/metrics.ts +0 -95
- package/src/transports/rest.ts +0 -161
- package/src/transports/util.ts +0 -63
- package/src/transports/websocket.ts +0 -238
- package/src/util/expiring-sorted-set.ts +0 -52
- package/src/util/index.ts +0 -20
- package/src/util/logger.ts +0 -69
- package/src/util/request.ts +0 -115
- package/src/validation/error.ts +0 -116
- package/src/validation/index.ts +0 -101
- package/src/validation/input-params.ts +0 -45
- package/src/validation/override-functions.ts +0 -44
- package/src/validation/preset-tokens.json +0 -23
- package/src/validation/validator.ts +0 -384
- package/test/adapter.test.ts +0 -27
- package/test/background-executor.test.ts +0 -109
- package/test/cache/cache-key.test.ts +0 -96
- package/test/cache/helper.ts +0 -101
- package/test/cache/local.test.ts +0 -54
- package/test/cache/redis.test.ts +0 -89
- package/test/correlation.test.ts +0 -114
- package/test/index.test.ts +0 -37
- package/test/metrics/feed-id.test.ts +0 -33
- package/test/metrics/helper.ts +0 -14
- package/test/metrics/labels.test.ts +0 -36
- package/test/metrics/metrics.test.ts +0 -267
- package/test/metrics/redis-metrics.test.ts +0 -113
- package/test/metrics/warmer-metrics.test.ts +0 -192
- package/test/metrics/ws-metrics.test.ts +0 -225
- package/test/rate-limit-config.test.ts +0 -243
- package/test/transports/batch.test.ts +0 -465
- package/test/transports/rest.test.ts +0 -242
- package/test/transports/websocket.test.ts +0 -183
- package/test/tsconfig.json +0 -5
- package/test/util.ts +0 -76
- package/test/validation.test.ts +0 -169
- package/test.sh +0 -20
- package/tsconfig.json +0 -24
- package/typedoc.json +0 -6
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Validator = void 0;
|
|
7
|
+
const error_1 = require("./error");
|
|
8
|
+
const input_params_1 = require("./input-params");
|
|
9
|
+
const util_1 = require("../util");
|
|
10
|
+
const preset_tokens_json_1 = __importDefault(require("./preset-tokens.json"));
|
|
11
|
+
// Don't want to get requester in just yet, only copying the static method 'errored'
|
|
12
|
+
const requesterErrored = (jobRunID = '1', error = undefined, statusCode = 500, feedID = undefined) => {
|
|
13
|
+
if (error instanceof error_1.AdapterError) {
|
|
14
|
+
error.jobRunID = jobRunID;
|
|
15
|
+
if (feedID) {
|
|
16
|
+
error.feedID = feedID;
|
|
17
|
+
}
|
|
18
|
+
return error.toJSONResponse();
|
|
19
|
+
}
|
|
20
|
+
if (error instanceof Error) {
|
|
21
|
+
return new error_1.AdapterError({
|
|
22
|
+
jobRunID,
|
|
23
|
+
statusCode,
|
|
24
|
+
message: error.message,
|
|
25
|
+
cause: error,
|
|
26
|
+
feedID,
|
|
27
|
+
}).toJSONResponse();
|
|
28
|
+
}
|
|
29
|
+
return new error_1.AdapterError({ jobRunID, statusCode, message: error, feedID }).toJSONResponse();
|
|
30
|
+
};
|
|
31
|
+
class Validator {
|
|
32
|
+
constructor(input = { id: '1', data: {} }, inputConfigs = {}, inputOptions = {}, validatorOptions = {}) {
|
|
33
|
+
// OverrideSymbol = (adapter: string, symbol?: string | string[]): string | string[] => {
|
|
34
|
+
// Const defaultSymbol = symbol || this.validated.data.base
|
|
35
|
+
// If (!defaultSymbol) this.throwInvalid(`Required parameter not supplied: base`)
|
|
36
|
+
// // TODO: Will never be reached, because the presetSymbols are used as default overrides
|
|
37
|
+
// If (!this.validated.overrides) return defaultSymbol
|
|
38
|
+
// If (!Array.isArray(defaultSymbol))
|
|
39
|
+
// Return (
|
|
40
|
+
// This.validated.overrides.get(adapter.toLowerCase())?.get(defaultSymbol.toLowerCase()) ||
|
|
41
|
+
// DefaultSymbol
|
|
42
|
+
// )
|
|
43
|
+
// Const multiple: string[] = []
|
|
44
|
+
// For (const sym of defaultSymbol) {
|
|
45
|
+
// Const overrided = this.validated.overrides.get(adapter.toLowerCase())?.get(sym.toLowerCase())
|
|
46
|
+
// If (!overrided) multiple.push(sym)
|
|
47
|
+
// Else multiple.push(overrided)
|
|
48
|
+
// }
|
|
49
|
+
// Return multiple
|
|
50
|
+
// }
|
|
51
|
+
// OverrideToken = (symbol: string, network = 'ethereum'): string | undefined => {
|
|
52
|
+
// Return this.validated.tokenOverrides?.get(network.toLowerCase())?.get(symbol.toLowerCase())
|
|
53
|
+
// }
|
|
54
|
+
// OverrideIncludes = (from: string, to: string): IncludePair | undefined => {
|
|
55
|
+
// // Search through `presetIncludes` to find matching override for adapter and to/from pairing.
|
|
56
|
+
// Const pairs = (
|
|
57
|
+
// This.validated.includes?.filter(
|
|
58
|
+
// (val: string | Includes) => typeof val !== 'string',
|
|
59
|
+
// ) as Includes[]
|
|
60
|
+
// ).filter(
|
|
61
|
+
// (pair) =>
|
|
62
|
+
// Pair.from.toLowerCase() === from.toLowerCase() &&
|
|
63
|
+
// Pair.to.toLowerCase() === to.toLowerCase(),
|
|
64
|
+
// )
|
|
65
|
+
// If (!pairs || !pairs[0] || !pairs[0].includes || !pairs[0].includes[0]) {
|
|
66
|
+
// Return
|
|
67
|
+
// }
|
|
68
|
+
// Return pairs[0].includes[0]
|
|
69
|
+
// }
|
|
70
|
+
// OverrideReverseLookup = (adapter: string, type: OverrideType, symbol: string): string => {
|
|
71
|
+
// Const overrides: Map<string, string> | undefined = this.validated?.[type]?.get(
|
|
72
|
+
// Adapter.toLowerCase(),
|
|
73
|
+
// )
|
|
74
|
+
// If (!overrides) return symbol
|
|
75
|
+
// Let originalSymbol: string | undefined
|
|
76
|
+
// Overrides.forEach((overridden, original) => {
|
|
77
|
+
// If (overridden.toLowerCase() === symbol.toLowerCase()) originalSymbol = original
|
|
78
|
+
// })
|
|
79
|
+
// Return originalSymbol || symbol
|
|
80
|
+
// }
|
|
81
|
+
this.formatOverride = (param) => {
|
|
82
|
+
const _throwInvalid = () => this.throwInvalid(`Parameter supplied with wrong format: "override"`);
|
|
83
|
+
if (!(0, util_1.isObject)(param)) {
|
|
84
|
+
_throwInvalid();
|
|
85
|
+
}
|
|
86
|
+
const _isValid = Object.values(param).every(util_1.isObject);
|
|
87
|
+
if (!_isValid) {
|
|
88
|
+
_throwInvalid();
|
|
89
|
+
}
|
|
90
|
+
const _keyToLowerCase = (entry) => {
|
|
91
|
+
return [entry[0].toLowerCase(), entry[1]];
|
|
92
|
+
};
|
|
93
|
+
return new Map(Object.entries(param)
|
|
94
|
+
.map(_keyToLowerCase)
|
|
95
|
+
.map(([key, value]) => [key, new Map(Object.entries(value).map(_keyToLowerCase))]));
|
|
96
|
+
};
|
|
97
|
+
this.formatIncludeOverrides = (param) => {
|
|
98
|
+
const _throwInvalid = () => this.throwInvalid(`Parameter supplied with wrong format: "includes"`);
|
|
99
|
+
if (!(0, util_1.isArray)(param)) {
|
|
100
|
+
_throwInvalid();
|
|
101
|
+
}
|
|
102
|
+
const _isValid = Object.values(param).every((val) => (0, util_1.isObject)(val) || typeof val === 'string');
|
|
103
|
+
if (!_isValid) {
|
|
104
|
+
_throwInvalid();
|
|
105
|
+
}
|
|
106
|
+
return param;
|
|
107
|
+
};
|
|
108
|
+
this.throwInvalid = (message) => {
|
|
109
|
+
throw new error_1.AdapterError({ jobRunID: this.validated.id, statusCode: 400, message });
|
|
110
|
+
};
|
|
111
|
+
this.input = { ...input };
|
|
112
|
+
if (!this.input.id) {
|
|
113
|
+
this.input.id = '1';
|
|
114
|
+
} // TODO Please remove these once "no any" strict typing is enabled
|
|
115
|
+
if (!this.input.data) {
|
|
116
|
+
this.input.data = {};
|
|
117
|
+
}
|
|
118
|
+
this.inputConfigs = { ...input_params_1.baseInputParameters, ...inputConfigs };
|
|
119
|
+
this.inputOptions = { ...inputOptions };
|
|
120
|
+
this.validatorOptions = {
|
|
121
|
+
shouldThrowError: true,
|
|
122
|
+
includes: [],
|
|
123
|
+
overrides: {},
|
|
124
|
+
...validatorOptions,
|
|
125
|
+
};
|
|
126
|
+
this.validated = { id: this.input.id, data: {} };
|
|
127
|
+
this.validateInput();
|
|
128
|
+
this.validateOverrides('overrides', this.validatorOptions.overrides);
|
|
129
|
+
this.validateOverrides('tokenOverrides', preset_tokens_json_1.default);
|
|
130
|
+
this.validateIncludeOverrides();
|
|
131
|
+
this.checkDuplicateInputParams(inputConfigs);
|
|
132
|
+
}
|
|
133
|
+
validateInput() {
|
|
134
|
+
try {
|
|
135
|
+
for (const key in this.inputConfigs) {
|
|
136
|
+
this.validateObjectParam(key, this.validatorOptions.shouldThrowError);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
catch (e) {
|
|
140
|
+
this.parseError(e);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
validateOverrides(path, preset) {
|
|
144
|
+
try {
|
|
145
|
+
if (!this.input.data?.[path]) {
|
|
146
|
+
this.validated[path] = this.formatOverride(preset);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
this.validated[path] = this.formatOverride({ ...preset, ...this.input.data[path] });
|
|
150
|
+
}
|
|
151
|
+
catch (e) {
|
|
152
|
+
this.parseError(e);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
checkDuplicateInputParams(inputConfig) {
|
|
156
|
+
let aliases = [];
|
|
157
|
+
for (const key in inputConfig) {
|
|
158
|
+
const param = inputConfig[key];
|
|
159
|
+
if (Array.isArray(param)) {
|
|
160
|
+
aliases = aliases.concat(param);
|
|
161
|
+
}
|
|
162
|
+
else if (typeof inputConfig === 'boolean') {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
aliases.push(key);
|
|
167
|
+
if (typeof param === 'object' && 'aliases' in param && Array.isArray(param.aliases)) {
|
|
168
|
+
aliases = aliases.concat(param.aliases);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (aliases.length !== new Set(aliases).size) {
|
|
173
|
+
this.throwInvalid('Duplicate Input Aliases');
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
validateIncludeOverrides() {
|
|
177
|
+
try {
|
|
178
|
+
this.validated.includes = this.formatIncludeOverrides([
|
|
179
|
+
...(Array.isArray(this.input.data?.includes) ? this.input.data.includes : []),
|
|
180
|
+
...(this.validatorOptions.includes || []),
|
|
181
|
+
]);
|
|
182
|
+
}
|
|
183
|
+
catch (e) {
|
|
184
|
+
this.parseError(e);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
parseError(error) {
|
|
188
|
+
if (!(error instanceof Error)) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
const message = 'Error validating input.';
|
|
192
|
+
if (error instanceof error_1.AdapterError) {
|
|
193
|
+
this.error = error;
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
this.error = new error_1.AdapterError({
|
|
197
|
+
jobRunID: this.validated.id,
|
|
198
|
+
statusCode: 400,
|
|
199
|
+
message,
|
|
200
|
+
cause: error,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
this.errored = requesterErrored(this.validated.id, this.error);
|
|
204
|
+
if (this.validatorOptions.shouldThrowError) {
|
|
205
|
+
throw this.error;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
validateObjectParam(key, shouldThrowError = true) {
|
|
209
|
+
const inputConfig = this.inputConfigs[key];
|
|
210
|
+
const usedKey = this.getUsedKey(key, inputConfig.aliases ?? []);
|
|
211
|
+
const param = usedKey
|
|
212
|
+
? this.input.data[usedKey] ?? inputConfig.default
|
|
213
|
+
: inputConfig.default;
|
|
214
|
+
if (shouldThrowError) {
|
|
215
|
+
const paramIsDefined = !(param === undefined || param === null || param === '');
|
|
216
|
+
if (inputConfig.required && !paramIsDefined) {
|
|
217
|
+
this.throwInvalid(`Required parameter ${key} must be non-null and non-empty`);
|
|
218
|
+
}
|
|
219
|
+
if (paramIsDefined) {
|
|
220
|
+
if (inputConfig.type) {
|
|
221
|
+
const primitiveTypes = ['boolean', 'number', 'bigint', 'string'];
|
|
222
|
+
if (![...primitiveTypes, 'array', 'object'].includes(inputConfig.type)) {
|
|
223
|
+
this.throwInvalid(`${key} parameter has unrecognized type ${inputConfig.type}`);
|
|
224
|
+
}
|
|
225
|
+
if (primitiveTypes.includes(inputConfig.type) && typeof param !== inputConfig.type) {
|
|
226
|
+
this.throwInvalid(`${key} parameter must be of type ${inputConfig.type}`);
|
|
227
|
+
}
|
|
228
|
+
if (inputConfig.type === 'array' && (!Array.isArray(param) || param.length === 0)) {
|
|
229
|
+
this.throwInvalid(`${key} parameter must be a non-empty array`);
|
|
230
|
+
}
|
|
231
|
+
if (inputConfig.type === 'object' &&
|
|
232
|
+
(!param ||
|
|
233
|
+
Array.isArray(param) ||
|
|
234
|
+
typeof param !== inputConfig.type ||
|
|
235
|
+
Object.keys(param).length === 0)) {
|
|
236
|
+
this.throwInvalid(`${key} parameter must be an object with at least one property`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// If (inputConfig.options) {
|
|
240
|
+
// Const tolcase = (o: any) => (typeof o === 'string' ? o.toLowerCase() : o)
|
|
241
|
+
// Const formattedOptions = inputConfig.options.map(tolcase)
|
|
242
|
+
// Const formattedParam = tolcase(param)
|
|
243
|
+
// If (!formattedOptions.includes(formattedParam))
|
|
244
|
+
// This.throwInvalid(
|
|
245
|
+
// `${key} parameter '${formattedParam}' is not in the set of available options: ${formattedOptions.join(
|
|
246
|
+
// ',',
|
|
247
|
+
// )}`,
|
|
248
|
+
// )
|
|
249
|
+
// }
|
|
250
|
+
// For (const dependency of inputConfig.dependsOn ?? []) {
|
|
251
|
+
// Const usedDependencyKey = this.getUsedKey(
|
|
252
|
+
// Dependency,
|
|
253
|
+
// (this.inputConfigs[dependency] as InputParameter).aliases ?? [],
|
|
254
|
+
// )
|
|
255
|
+
// If (!usedDependencyKey) this.throwInvalid(`${key} dependency ${dependency} not supplied`)
|
|
256
|
+
// }
|
|
257
|
+
// For (const exclusive of inputConfig.exclusive ?? []) {
|
|
258
|
+
// Const usedExclusiveKey = this.getUsedKey(
|
|
259
|
+
// Exclusive,
|
|
260
|
+
// (this.inputConfigs[exclusive] as InputParameter).aliases ?? [],
|
|
261
|
+
// )
|
|
262
|
+
// If (usedExclusiveKey)
|
|
263
|
+
// This.throwInvalid(`${key} cannot be supplied concurrently with ${exclusive}`)
|
|
264
|
+
// }
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
this.validated.data[key] = param;
|
|
268
|
+
}
|
|
269
|
+
validateOptionalParam(param, key, options) {
|
|
270
|
+
if (param && options) {
|
|
271
|
+
if (!Array.isArray(options)) {
|
|
272
|
+
this.throwInvalid(`Parameter options for ${key} must be of an Array type`);
|
|
273
|
+
}
|
|
274
|
+
if (!options.includes(param)) {
|
|
275
|
+
this.throwInvalid(`${param} is not a supported ${key} option. Must be one of ${options}`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
this.validated.data[key] = param;
|
|
279
|
+
}
|
|
280
|
+
validateRequiredParam(param, key, options) {
|
|
281
|
+
if (typeof param === 'undefined' || param === '') {
|
|
282
|
+
this.throwInvalid(`Required parameter not supplied: ${key}`);
|
|
283
|
+
}
|
|
284
|
+
if (options) {
|
|
285
|
+
if (!Array.isArray(options)) {
|
|
286
|
+
this.throwInvalid(`Parameter options for ${key} must be of an Array type`);
|
|
287
|
+
}
|
|
288
|
+
if (!options.includes(param)) {
|
|
289
|
+
this.throwInvalid(`${param} is not a supported ${key} option. Must be one of ${options.join(' || ')}`);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
this.validated.data[key] = param;
|
|
293
|
+
}
|
|
294
|
+
getUsedKey(key, keyArray) {
|
|
295
|
+
const comparisonArray = [...keyArray];
|
|
296
|
+
if (!comparisonArray.includes(key)) {
|
|
297
|
+
comparisonArray.push(key);
|
|
298
|
+
}
|
|
299
|
+
const inputParamKeys = Object.keys(this.input.data);
|
|
300
|
+
return inputParamKeys.find((k) => comparisonArray.includes(k));
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
exports.Validator = Validator;
|
package/.c8rc.json
DELETED
package/.eslintignore
DELETED
package/.eslintrc.js
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
// https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/README.md
|
|
2
|
-
module.exports = {
|
|
3
|
-
root: true,
|
|
4
|
-
parser: '@typescript-eslint/parser',
|
|
5
|
-
plugins: ['@typescript-eslint', 'eslint-plugin-tsdoc'],
|
|
6
|
-
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
|
|
7
|
-
rules: {
|
|
8
|
-
'tsdoc/syntax': 'warn',
|
|
9
|
-
|
|
10
|
-
// Problems
|
|
11
|
-
'array-callback-return': [
|
|
12
|
-
'error',
|
|
13
|
-
{
|
|
14
|
-
allowImplicit: false,
|
|
15
|
-
checkForEach: true,
|
|
16
|
-
},
|
|
17
|
-
],
|
|
18
|
-
'no-constant-binary-expression': 'error',
|
|
19
|
-
'no-constructor-return': 'error',
|
|
20
|
-
'no-duplicate-imports': 'error',
|
|
21
|
-
'no-promise-executor-return': 'error',
|
|
22
|
-
'no-self-compare': 'error',
|
|
23
|
-
'no-template-curly-in-string': 'error',
|
|
24
|
-
'no-unmodified-loop-condition': 'error',
|
|
25
|
-
'no-unreachable-loop': 'error',
|
|
26
|
-
'no-unused-private-class-members': 'error',
|
|
27
|
-
'require-atomic-updates': 'error',
|
|
28
|
-
|
|
29
|
-
// Suggestions
|
|
30
|
-
'capitalized-comments': ['error', 'always', { ignoreConsecutiveComments: true }],
|
|
31
|
-
complexity: ['error', 25], // TODO: Should be lower (15?), but validator has complex methods
|
|
32
|
-
curly: 'error',
|
|
33
|
-
'default-case-last': 'error',
|
|
34
|
-
'default-param-last': 'error',
|
|
35
|
-
eqeqeq: ['error', 'smart'],
|
|
36
|
-
'func-names': 'error',
|
|
37
|
-
'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
|
|
38
|
-
'grouped-accessor-pairs': ['error', 'getBeforeSet'],
|
|
39
|
-
'max-depth': ['error', 4], // TODO: Should be lower (3), but validator has complex methods
|
|
40
|
-
'max-nested-callbacks': ['error', 2],
|
|
41
|
-
'max-params': ['error', 4], // TODO: Should be lower (3), but validator has complex methods,
|
|
42
|
-
'new-cap': ['error', { newIsCapExceptions: ['ctor'] }],
|
|
43
|
-
'no-caller': 'error',
|
|
44
|
-
'no-confusing-arrow': [
|
|
45
|
-
'error',
|
|
46
|
-
{
|
|
47
|
-
allowParens: true,
|
|
48
|
-
},
|
|
49
|
-
],
|
|
50
|
-
'no-console': ['warn'], // We want this to debug, but the check workflow should accept no warns
|
|
51
|
-
'no-div-regex': 'error',
|
|
52
|
-
'no-eval': 'error',
|
|
53
|
-
'no-extend-native': 'error',
|
|
54
|
-
'no-extra-bind': 'error',
|
|
55
|
-
'no-extra-label': 'error',
|
|
56
|
-
'no-extra-semi': 'error',
|
|
57
|
-
'no-floating-decimal': 'error',
|
|
58
|
-
'no-implied-eval': 'error',
|
|
59
|
-
'no-invalid-this': 'error',
|
|
60
|
-
'no-labels': 'error',
|
|
61
|
-
'no-lonely-if': 'error',
|
|
62
|
-
'no-multi-assign': 'error',
|
|
63
|
-
'no-multi-str': 'error',
|
|
64
|
-
'no-nested-ternary': 'error',
|
|
65
|
-
'no-new': 'error',
|
|
66
|
-
'no-new-func': 'error',
|
|
67
|
-
'no-new-object': 'error',
|
|
68
|
-
'no-new-wrappers': 'error',
|
|
69
|
-
'no-param-reassign': 'error',
|
|
70
|
-
'no-proto': 'error',
|
|
71
|
-
'no-return-assign': 'error',
|
|
72
|
-
'no-return-await': 'error',
|
|
73
|
-
'no-sequences': 'error',
|
|
74
|
-
'no-shadow': 'off',
|
|
75
|
-
'@typescript-eslint/no-shadow': 'error', // https://stackoverflow.com/questions/63961803/eslint-says-all-enums-in-typescript-app-are-already-declared-in-the-upper-scope
|
|
76
|
-
'no-unneeded-ternary': 'error',
|
|
77
|
-
'no-useless-call': 'error',
|
|
78
|
-
'no-useless-computed-key': 'error',
|
|
79
|
-
'no-useless-concat': 'error',
|
|
80
|
-
'no-useless-rename': 'error',
|
|
81
|
-
'no-var': 'error',
|
|
82
|
-
'operator-assignment': ['error', 'always'],
|
|
83
|
-
'prefer-arrow-callback': 'error',
|
|
84
|
-
'prefer-const': 'error',
|
|
85
|
-
'prefer-exponentiation-operator': 'error',
|
|
86
|
-
'prefer-object-spread': 'error',
|
|
87
|
-
'prefer-promise-reject-errors': 'error',
|
|
88
|
-
'prefer-regex-literals': 'error',
|
|
89
|
-
'prefer-rest-params': 'error',
|
|
90
|
-
'prefer-spread': 'error',
|
|
91
|
-
'prefer-template': 'error',
|
|
92
|
-
'spaced-comment': ['error', 'always'],
|
|
93
|
-
'symbol-description': 'error',
|
|
94
|
-
yoda: 'error',
|
|
95
|
-
},
|
|
96
|
-
}
|
package/.github/README.MD
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# Github workflows for EAv3 Framework
|
|
2
|
-
|
|
3
|
-
**Please note that this work is in progress. The README may not be accurate**
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
This directory contains a basic GitHub workflow that builds, tests, and ultimately publishes the EAv3 Framework to NPM
|
|
7
|
-
1. Setup (caches dependencies to speed up other steps)
|
|
8
|
-
2. Build/Prepare/Preflight (all the following happen at the same time)
|
|
9
|
-
1. yarn build => publish artifact of build
|
|
10
|
-
2. yarn lint
|
|
11
|
-
3. yarn test
|
|
12
|
-
3. Publish (currently unimplemented)
|
|
13
|
-
|
|
14
|
-
### Some steps that still need to be added in:
|
|
15
|
-
1. Check that changelog has an entry matching the current version in package.json
|
|
16
|
-
2. Check if a package is already published to NPM, and DON'T overwrite it unless a parameter explicitly allowing an overwrite has been passed
|
|
17
|
-
3. npm-check step that produces a report as an artifact
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
name: 'Setup'
|
|
2
|
-
description: 'Sets up the project, installs dependencies, and builds'
|
|
3
|
-
runs:
|
|
4
|
-
using: 'composite'
|
|
5
|
-
steps:
|
|
6
|
-
- uses: actions/setup-node@v3
|
|
7
|
-
with:
|
|
8
|
-
node-version: 16.x
|
|
9
|
-
registry-url: https://registry.npmjs.org
|
|
10
|
-
always-auth: true
|
|
11
|
-
cache: yarn
|
|
12
|
-
- run: yarn install --frozen-lockfile
|
|
13
|
-
shell: bash
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# This is the entry point for CI. It will setup the application, then run lint, test, and eventually publish if not the master or main branch
|
|
2
|
-
name: 'Main'
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- master
|
|
7
|
-
pull_request: ~
|
|
8
|
-
|
|
9
|
-
jobs:
|
|
10
|
-
setup: # Load the dependencies cache for all jobs
|
|
11
|
-
runs-on: ubuntu-latest
|
|
12
|
-
steps:
|
|
13
|
-
- uses: actions/checkout@v3
|
|
14
|
-
- uses: ./.github/actions/setup
|
|
15
|
-
build:
|
|
16
|
-
needs: setup
|
|
17
|
-
runs-on: ubuntu-latest
|
|
18
|
-
concurrency: build-${{ github.ref}}
|
|
19
|
-
steps:
|
|
20
|
-
- uses: actions/checkout@v3
|
|
21
|
-
- uses: ./.github/actions/setup
|
|
22
|
-
- run: yarn build
|
|
23
|
-
lint:
|
|
24
|
-
needs: setup
|
|
25
|
-
runs-on: ubuntu-latest
|
|
26
|
-
concurrency: lint-${{ github.ref }}
|
|
27
|
-
steps:
|
|
28
|
-
- uses: actions/checkout@v3
|
|
29
|
-
- uses: ./.github/actions/setup
|
|
30
|
-
- run: yarn lint
|
|
31
|
-
- run: yarn prettier --check **/*.{ts,md}
|
|
32
|
-
test:
|
|
33
|
-
needs: setup
|
|
34
|
-
concurrency: test-${{ github.ref }}
|
|
35
|
-
runs-on: ubuntu-latest
|
|
36
|
-
steps:
|
|
37
|
-
- uses: actions/checkout@v3
|
|
38
|
-
- uses: ./.github/actions/setup
|
|
39
|
-
- run: yarn test
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# This is the entry point for CI. It will setup the application, then run lint, test, and eventually publish if not the master or main branch
|
|
2
|
-
name: 'Publish'
|
|
3
|
-
on:
|
|
4
|
-
workflow_dispatch:
|
|
5
|
-
push:
|
|
6
|
-
branches:
|
|
7
|
-
- master
|
|
8
|
-
jobs:
|
|
9
|
-
publish: # Load the dependencies cache for all jobs
|
|
10
|
-
runs-on: ubuntu-latest
|
|
11
|
-
environment: main
|
|
12
|
-
steps:
|
|
13
|
-
- uses: actions/checkout@v3
|
|
14
|
-
- uses: ./.github/actions/setup
|
|
15
|
-
- run: npm publish --access restricted #scoped packages are restricted by default, but this is set because not all branches currently have a scoped package name
|
|
16
|
-
env:
|
|
17
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/.prettierignore
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
# don't ever lint node_modules
|
|
2
|
-
node_modules
|
|
3
|
-
# don't lint build output (make sure it's set to your correct build folder name)
|
|
4
|
-
dist
|
|
5
|
-
# don't lint nyc coverage output
|
|
6
|
-
coverage
|
|
7
|
-
test-payload.json
|
|
8
|
-
.yarn
|
|
9
|
-
.vscode
|
|
10
|
-
.pnp.cjs
|
|
11
|
-
.pnp.loader.mjs
|
|
12
|
-
|
|
13
|
-
packages/k6/k8s/templates
|
package/.yarnrc
DELETED
|
File without changes
|
package/README.md
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
# EA Framework v3
|
|
2
|
-
|
|
3
|
-
External adapters and its core framework serve as middleware to facilitate connections between Chainlink Nodes and Data Providers (DP). Their main purpose is threefold:
|
|
4
|
-
|
|
5
|
-
- Abstract provider specific details, specifically:
|
|
6
|
-
- Transport (REST, WebSockets, RPC, SSE, etc.)
|
|
7
|
-
- Authentication (login flows, keys)
|
|
8
|
-
- Accept normalized request payloads and translate into the provider's interface (this also includes things like symbols/tickers)
|
|
9
|
-
- Parse provider responses into the desired data points (e.g. price from crypto endpoint)
|
|
10
|
-
- Make the overall system more efficient by using as few resources (e.g. API credits, networking traffic, CPU usage) as possible to fetch data, achieved by features like:
|
|
11
|
-
- Caching: since DPs update data at various times and a request to their API incurs a certain latency, EAs keep a cache of values to
|
|
12
|
-
- Provide responses to the Chainlink Nodes as quickly as possible
|
|
13
|
-
- Communicate with DPs only when necessary
|
|
14
|
-
- Cache Warming: in order to make as many of the requests to EAs be fulfilled from the cache, EAs fetch values from DPs asynchronously to keep the local ones fresh.
|
|
15
|
-
- Batching: the CL Node requests feeds individually, but it's common for DPs to provide batch endpoints to get many data points at once. With Batching, EAs keep track of incoming requests and consolidate them into one batched request.
|
|
16
|
-
- Rate limiting: the EA framework additionally checks request rates (frequency) to make sure they fall within acceptable limits (like quotas for the DP's API, or adjusting based on the NOP's API tier).
|
|
17
|
-
- Perform off chain computations (think aggregations, indexing, or any sort of data processing)
|
|
18
|
-
|
|
19
|
-
By providing a framework that gives users easy access to those features, we reduce the complexity required for Nodes to communicate with DPs since by using EAs there is only one standardized way to do so, while at the same time optimizing said communication so it's as resource efficient as possible. It also makes internal and external development easier and faster, by serving as a strict guideline to implement and add new providers.
|
|
20
|
-
|
|
21
|
-
## Qs
|
|
22
|
-
|
|
23
|
-
- Store entire response in cache?
|
|
24
|
-
- Check for valid result in adapter response?
|
|
25
|
-
|
|
26
|
-
## Env vars
|
|
27
|
-
|
|
28
|
-
These are all existing env vars, marked DONE if they have been ported to this version, or N/A if the new version disregards them altogether.
|
|
29
|
-
|
|
30
|
-
| Name | State | Comments |
|
|
31
|
-
| :----------------------------------------- | :---: | :----------------------------------------------------------- |
|
|
32
|
-
| API_TIMEOUT | N/A | Only used for WS with handler.noHTtp = true |
|
|
33
|
-
| BASE_URL | √ | |
|
|
34
|
-
| CACHE_ENABLED | N/A | Cache is integral to this fw, not including this for now |
|
|
35
|
-
| CACHE_KEY_IGNORED_PROPS | ?? | Do we want this to be available in v3. Used for feed id |
|
|
36
|
-
| CACHE_KEY_GROUP | ?? | Dunno if this applies to this fw |
|
|
37
|
-
| CACHE_MAX_AGE | √ | |
|
|
38
|
-
| CACHE_MAX_ITEMS | - | Should add when replacing obj in local impl with LRU package |
|
|
39
|
-
| CACHE_MIN_AGE | - | Used for rate limiting |
|
|
40
|
-
| CACHE_REDIS_CONNECTION_TIMEOUT | - | TODO: Redis |
|
|
41
|
-
| CACHE_REDIS_HOST | - | TODO: Redis |
|
|
42
|
-
| CACHE_REDIS_MAX_QUEUED_ITEMS | - | TODO: Redis |
|
|
43
|
-
| CACHE_REDIS_MAX_RECONNECT_COOLDOWN | - | TODO: Redis |
|
|
44
|
-
| CACHE_REDIS_PASSWORD | - | TODO: Redis |
|
|
45
|
-
| CACHE_REDIS_PATH | - | TODO: Redis |
|
|
46
|
-
| CACHE_REDIS_PORT | - | TODO: Redis |
|
|
47
|
-
| CACHE_REDIS_TIMEOUT | - | TODO: Redis |
|
|
48
|
-
| CACHE_REDIS_URL | - | TODO: Redis |
|
|
49
|
-
| CACHE_TYPE | - | TODO: Cache factory |
|
|
50
|
-
| CACHE_UPDATE_AGE_ON_GET | N/A | No longer used in EA currently, apparently |
|
|
51
|
-
| DEBUG | | |
|
|
52
|
-
| DEFAULT_WS_HEARTBEAT_INTERVAL | | |
|
|
53
|
-
| EA_HOST | | |
|
|
54
|
-
| EA_PORT | √ | |
|
|
55
|
-
| ENV_ADAPTER_URL | | |
|
|
56
|
-
| ENV_API_ENDPOINT | | |
|
|
57
|
-
| ENV_API_KEY | | |
|
|
58
|
-
| ENV_API_TIMEOUT | | |
|
|
59
|
-
| ENV_API_VERBOSE | | |
|
|
60
|
-
| ENV_WS_API_ENDPOINT | | |
|
|
61
|
-
| ENV_WS_API_KEY | | |
|
|
62
|
-
| ERROR_CAPACITY | | |
|
|
63
|
-
| EXPERIMENTAL_METRICS_ENABLED | √ | Maintaining for backwards compatibility. Defaults to true |
|
|
64
|
-
| LEGACY_ENV_ADAPTER_URL | | |
|
|
65
|
-
| LOG_LEVEL | | |
|
|
66
|
-
| METRICS_ENABLED | √ | Defaults to true |
|
|
67
|
-
| METRICS_NAME | √ | |
|
|
68
|
-
| METRICS_PORT | √ | |
|
|
69
|
-
| METRICS_USE_BASE_URL | √ | |
|
|
70
|
-
| NODE_ENV | | |
|
|
71
|
-
| npm_package_version | | |
|
|
72
|
-
| RATE_LIMIT_API_TIER | | |
|
|
73
|
-
| RATE_LIMIT_CAPACITY | | |
|
|
74
|
-
| RATE_LIMIT_CAPACITY_MINUTE | | |
|
|
75
|
-
| RATE_LIMIT_CAPACITY_SECOND | | |
|
|
76
|
-
| RATE_LIMIT_ENABLED | | |
|
|
77
|
-
| RECORD | | |
|
|
78
|
-
| REQUEST_COALESCING_ENABLED | | |
|
|
79
|
-
| REQUEST_COALESCING_ENTROPY_MAX | | |
|
|
80
|
-
| REQUEST_COALESCING_INTERVAL | | |
|
|
81
|
-
| REQUEST_COALESCING_INTERVAL_COEFFICIENT | | |
|
|
82
|
-
| REQUEST_COALESCING_INTERVAL_MAX | | |
|
|
83
|
-
| REQUEST_COALESCING_MAX_RETRIES | | |
|
|
84
|
-
| RETRY | | |
|
|
85
|
-
| SERVER_RATE_LIMIT_MAX | | |
|
|
86
|
-
| SERVER_SLOW_DOWN_AFTER_FACTOR | | |
|
|
87
|
-
| SERVER_SLOW_DOWN_DELAY_MS | | |
|
|
88
|
-
| TIMEOUT | | |
|
|
89
|
-
| WARMUP_ENABLED | | |
|
|
90
|
-
| WARMUP_INTERVAL | | |
|
|
91
|
-
| WARMUP_SUBSCRIPTION_TTL | | |
|
|
92
|
-
| WARMUP_UNHEALTHY_THRESHOLD | | |
|
|
93
|
-
| WS_CONNECTION_KEY | | |
|
|
94
|
-
| WS_CONNECTION_LIMIT | | |
|
|
95
|
-
| WS_CONNECTION_RETRY_DELAY | | |
|
|
96
|
-
| WS_CONNECTION_RETRY_LIMIT | | |
|
|
97
|
-
| WS_CONNECTION_TTL | | |
|
|
98
|
-
| WS_ENABLED | N/A | Shouldn't be part of this fw |
|
|
99
|
-
| WS_SUBSCRIPTION_LIMIT | | |
|
|
100
|
-
| WS_SUBSCRIPTION_PRIORITY_LIST | | |
|
|
101
|
-
| WS_SUBSCRIPTION_TTL | | |
|
|
102
|
-
| WS_SUBSCRIPTION_UNRESPONSIVE_TTL | | |
|
|
103
|
-
| WS_TIME_UNTIL_HANDLE_NEXT_MESSAGE_OVERRIDE | | |
|
package/docker-compose.yaml
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# Very basic stack to demonstrate horizontal scaling
|
|
2
|
-
services:
|
|
3
|
-
redis:
|
|
4
|
-
image: redis
|
|
5
|
-
container_name: redis
|
|
6
|
-
|
|
7
|
-
coingecko-reader:
|
|
8
|
-
image: node:alpine
|
|
9
|
-
ports:
|
|
10
|
-
- 8080
|
|
11
|
-
deploy:
|
|
12
|
-
mode: replicated
|
|
13
|
-
replicas: 2
|
|
14
|
-
environment:
|
|
15
|
-
- DISABLE_BACKGROUND_EXECUTOR=true
|
|
16
|
-
volumes:
|
|
17
|
-
- ./:/home/node/app
|
|
18
|
-
command: node /home/node/app/dist/test.js
|
|
19
|
-
|
|
20
|
-
coingecko-writer:
|
|
21
|
-
image: node:alpine
|
|
22
|
-
volumes:
|
|
23
|
-
- ./:/home/node/app
|
|
24
|
-
environment:
|
|
25
|
-
- DISABLE_REST_API=true
|
|
26
|
-
command: node /home/node/app/dist/test.js
|
|
27
|
-
|
|
28
|
-
lb:
|
|
29
|
-
image: dockercloud/haproxy
|
|
30
|
-
links:
|
|
31
|
-
- coingecko-reader
|
|
32
|
-
ports:
|
|
33
|
-
- '80:80'
|
|
34
|
-
volumes:
|
|
35
|
-
- /var/run/docker.sock:/var/run/docker.sock
|