@chainlink/external-adapter-framework 0.0.22 → 0.0.25

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.
Files changed (78) hide show
  1. package/cache/factory.js +27 -0
  2. package/cache/index.js +16 -1
  3. package/cache/local.js +26 -0
  4. package/cache/redis.js +45 -0
  5. package/package.json +2 -2
  6. package/transports/batch-warming.js +36 -0
  7. package/transports/rest.js +32 -0
  8. package/transports/util.js +33 -0
  9. package/transports/websocket.js +31 -0
  10. package/adapter.d.ts +0 -139
  11. package/background-executor.d.ts +0 -9
  12. package/cache/factory.d.ts +0 -6
  13. package/cache/index.d.ts +0 -94
  14. package/cache/local.d.ts +0 -23
  15. package/cache/metrics.d.ts +0 -27
  16. package/cache/redis.d.ts +0 -16
  17. package/config/index.d.ts +0 -258
  18. package/config/provider-limits.d.ts +0 -27
  19. package/examples/bank-frick/accounts.d.ts +0 -39
  20. package/examples/bank-frick/config/index.d.ts +0 -4
  21. package/examples/bank-frick/index.d.ts +0 -2
  22. package/examples/bank-frick/util.d.ts +0 -4
  23. package/examples/coingecko/batch-warming.d.ts +0 -7
  24. package/examples/coingecko/batch-warming.js +0 -53
  25. package/examples/coingecko/index.d.ts +0 -2
  26. package/examples/coingecko/index.js +0 -11
  27. package/examples/coingecko/rest.d.ts +0 -12
  28. package/examples/coingecko/rest.js +0 -51
  29. package/examples/coingecko/src/config/index.d.ts +0 -2
  30. package/examples/coingecko/src/cryptoUtils.d.ts +0 -31
  31. package/examples/coingecko/src/endpoint/coins.d.ts +0 -9
  32. package/examples/coingecko/src/endpoint/crypto-marketcap.d.ts +0 -3
  33. package/examples/coingecko/src/endpoint/crypto-volume.d.ts +0 -3
  34. package/examples/coingecko/src/endpoint/crypto.d.ts +0 -3
  35. package/examples/coingecko/src/endpoint/dominance.d.ts +0 -3
  36. package/examples/coingecko/src/endpoint/global-marketcap.d.ts +0 -3
  37. package/examples/coingecko/src/endpoint/index.d.ts +0 -6
  38. package/examples/coingecko/src/globalUtils.d.ts +0 -27
  39. package/examples/coingecko/src/index.d.ts +0 -4
  40. package/examples/coingecko/test/e2e/adapter.test.js +0 -262
  41. package/examples/coingecko/test/integration/adapter.test.js +0 -264
  42. package/examples/coingecko/test/integration/capturedRequests.json +0 -1
  43. package/examples/coingecko/test/integration/fixtures.js +0 -41
  44. package/examples/coingecko-old/batch-warming.d.ts +0 -7
  45. package/examples/coingecko-old/index.d.ts +0 -2
  46. package/examples/coingecko-old/rest.d.ts +0 -12
  47. package/examples/ncfx/config/index.d.ts +0 -12
  48. package/examples/ncfx/index.d.ts +0 -13
  49. package/examples/ncfx/websocket.d.ts +0 -47
  50. package/index.d.ts +0 -11
  51. package/metrics/constants.d.ts +0 -16
  52. package/metrics/index.d.ts +0 -15
  53. package/metrics/util.d.ts +0 -7
  54. package/rate-limiting/background/fixed-frequency.d.ts +0 -11
  55. package/rate-limiting/index.d.ts +0 -55
  56. package/rate-limiting/metrics.d.ts +0 -3
  57. package/rate-limiting/request/simple-counting.d.ts +0 -21
  58. package/test.d.ts +0 -1
  59. package/test.js +0 -6
  60. package/transports/batch-warming.d.ts +0 -35
  61. package/transports/index.d.ts +0 -73
  62. package/transports/metrics.d.ts +0 -22
  63. package/transports/rest.d.ts +0 -44
  64. package/transports/util.d.ts +0 -9
  65. package/transports/websocket.d.ts +0 -80
  66. package/util/index.d.ts +0 -12
  67. package/util/logger.d.ts +0 -42
  68. package/util/recordRequests.js +0 -45
  69. package/util/request.d.ts +0 -56
  70. package/util/subscription-set/expiring-sorted-set.d.ts +0 -22
  71. package/util/subscription-set/subscription-set.d.ts +0 -18
  72. package/util/test-payload-loader.d.ts +0 -25
  73. package/validation/error.d.ts +0 -50
  74. package/validation/index.d.ts +0 -5
  75. package/validation/input-params.d.ts +0 -15
  76. package/validation/override-functions.d.ts +0 -3
  77. package/validation/overrideFunctions.js +0 -40
  78. package/validation/validator.d.ts +0 -47
package/cache/factory.js CHANGED
@@ -1,4 +1,27 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
@@ -7,6 +30,7 @@ exports.CacheFactory = void 0;
7
30
  const ioredis_1 = __importDefault(require("ioredis"));
8
31
  const util_1 = require("../util");
9
32
  const local_1 = require("./local");
33
+ const cacheMetrics = __importStar(require("./metrics"));
10
34
  const redis_1 = require("./redis");
11
35
  const logger = (0, util_1.makeLogger)('CacheFactory');
12
36
  class CacheFactory {
@@ -24,6 +48,9 @@ class CacheFactory {
24
48
  path: config.CACHE_REDIS_PATH,
25
49
  timeout: config.CACHE_REDIS_TIMEOUT,
26
50
  });
51
+ redis.on('connect', () => {
52
+ cacheMetrics.redisConnectionsOpen.inc();
53
+ });
27
54
  return new redis_1.RedisCache(redis);
28
55
  }
29
56
  }
package/cache/index.js CHANGED
@@ -10,12 +10,25 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
10
10
  if (k2 === undefined) k2 = k;
11
11
  o[k2] = m[k];
12
12
  }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
13
25
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
26
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
27
  };
16
28
  Object.defineProperty(exports, "__esModule", { value: true });
17
29
  exports.buildCacheMiddleware = exports.pollResponseFromCache = exports.calculateKey = exports.calculateFeedId = exports.calculateCacheKey = void 0;
18
30
  const util_1 = require("../util");
31
+ const cacheMetrics = __importStar(require("./metrics"));
19
32
  __exportStar(require("./local"), exports);
20
33
  __exportStar(require("./redis"), exports);
21
34
  __exportStar(require("./factory"), exports);
@@ -144,8 +157,10 @@ const buildCacheMiddleware = (adapter) => async (req, res) => {
144
157
  if (response) {
145
158
  logger.debug('Found response from cache, sending that');
146
159
  if (adapter.config.METRICS_ENABLED && adapter.config.EXPERIMENTAL_METRICS_ENABLED) {
160
+ const label = cacheMetrics.cacheMetricsLabel(req.requestContext.cacheKey, req.requestContext.meta?.metrics?.feedId || 'N/A', adapter.config.CACHE_TYPE);
147
161
  // Record cache staleness and cache get count and value
148
- calculateStaleness(response.maxAge, adapter.config.CACHE_MAX_AGE);
162
+ const staleness = calculateStaleness(response.maxAge, adapter.config.CACHE_MAX_AGE);
163
+ cacheMetrics.cacheGet(label, response.result, staleness);
149
164
  req.requestContext.meta = {
150
165
  ...req.requestContext.meta,
151
166
  metrics: { ...req.requestContext.meta?.metrics, cacheHit: true },
package/cache/local.js CHANGED
@@ -1,7 +1,31 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  Object.defineProperty(exports, "__esModule", { value: true });
3
26
  exports.LocalCache = void 0;
4
27
  const util_1 = require("../util");
28
+ const cacheMetrics = __importStar(require("./metrics"));
5
29
  const logger = (0, util_1.makeLogger)('LocalCache');
6
30
  /**
7
31
  * Local implementation of a Cache. It uses a simple js Object, storing entries with both
@@ -45,6 +69,8 @@ class LocalCache {
45
69
  const feedId = value.meta?.metrics?.feedId;
46
70
  if (feedId) {
47
71
  // Record cache set count, max age, and staleness (set to 0 for cache set)
72
+ const label = cacheMetrics.cacheMetricsLabel(key, feedId, cacheMetrics.CacheTypes.Local);
73
+ cacheMetrics.cacheSet(label, ttl);
48
74
  }
49
75
  }
50
76
  async setMany(entries, ttl) {
package/cache/redis.js CHANGED
@@ -1,7 +1,31 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  Object.defineProperty(exports, "__esModule", { value: true });
3
26
  exports.RedisCache = void 0;
4
27
  const util_1 = require("../util");
28
+ const cacheMetrics = __importStar(require("./metrics"));
5
29
  const logger = (0, util_1.makeLogger)('RedisCache');
6
30
  /**
7
31
  * Redis implementation of a Cache. It uses a simple js Object, storing entries with both
@@ -16,6 +40,10 @@ class RedisCache {
16
40
  async get(key) {
17
41
  logger.trace(`Getting key ${key}`);
18
42
  const value = await this.client.get(key);
43
+ // Record get command sent to Redis
44
+ cacheMetrics.redisCommandsSentCount
45
+ .labels({ status: cacheMetrics.CMD_SENT_STATUS.SUCCESS, function_name: 'get' })
46
+ .inc();
19
47
  if (!value) {
20
48
  logger.debug(`No entry in redis cache for key "${key}", returning undefined`);
21
49
  return undefined;
@@ -25,6 +53,10 @@ class RedisCache {
25
53
  async delete(key) {
26
54
  logger.trace(`Deleting key ${key}`);
27
55
  await this.client.del(key);
56
+ // Record delete command sent to Redis
57
+ cacheMetrics.redisCommandsSentCount
58
+ .labels({ status: cacheMetrics.CMD_SENT_STATUS.SUCCESS, function_name: 'delete' })
59
+ .inc();
28
60
  }
29
61
  async set(key, value, ttl) {
30
62
  logger.trace(`Setting key ${key}`);
@@ -33,7 +65,13 @@ class RedisCache {
33
65
  const feedId = value.meta?.metrics?.feedId;
34
66
  if (feedId) {
35
67
  // Record cache set count, max age, and staleness (set to 0 for cache set)
68
+ const label = cacheMetrics.cacheMetricsLabel(key, feedId, cacheMetrics.CacheTypes.Redis);
69
+ cacheMetrics.cacheSet(label, ttl);
36
70
  }
71
+ // Record set command sent to Redis
72
+ cacheMetrics.redisCommandsSentCount
73
+ .labels({ status: cacheMetrics.CMD_SENT_STATUS.SUCCESS, function_name: 'set' })
74
+ .inc();
37
75
  }
38
76
  async setMany(entries, ttl) {
39
77
  logger.trace(`Setting a bunch of keys`);
@@ -48,8 +86,15 @@ class RedisCache {
48
86
  // Only record metrics if feed Id is present, otherwise assuming value is not adapter response to record
49
87
  const feedId = entry.value.meta?.metrics?.feedId;
50
88
  if (feedId) {
89
+ // Record cache set count, max age, and staleness (set to 0 for cache set)
90
+ const label = cacheMetrics.cacheMetricsLabel(entry.key, feedId, cacheMetrics.CacheTypes.Redis);
91
+ cacheMetrics.cacheSet(label, ttl);
51
92
  }
52
93
  }
94
+ // Record setMany command sent to Redis
95
+ cacheMetrics.redisCommandsSentCount
96
+ .labels({ status: cacheMetrics.CMD_SENT_STATUS.SUCCESS, function_name: 'exec' })
97
+ .inc();
53
98
  }
54
99
  }
55
100
  exports.RedisCache = RedisCache;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chainlink/external-adapter-framework",
3
- "version": "0.0.22",
3
+ "version": "0.0.25",
4
4
  "main": "dist/index.js",
5
5
  "license": "MIT",
6
6
  "dependencies": {
@@ -44,7 +44,7 @@
44
44
  "nock": "^13.2.4",
45
45
  "pino-pretty": "^7.6.0",
46
46
  "prettier": "^2.6.1",
47
- "ts-node-dev": "^2.0.0",
47
+ "ts-node-dev": "2.0.0",
48
48
  "typedoc": "^0.22.15"
49
49
  },
50
50
  "prettier": {
@@ -1,9 +1,35 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  Object.defineProperty(exports, "__esModule", { value: true });
3
26
  exports.BatchWarmingTransport = void 0;
4
27
  const util_1 = require("../util");
5
28
  const _1 = require("./");
6
29
  const util_2 = require("./util");
30
+ const rateLimitMetrics = __importStar(require("../rate-limiting/metrics"));
31
+ const cacheMetrics = __importStar(require("../cache/metrics"));
32
+ const WARMUP_BATCH_REQUEST_ID = '9002';
7
33
  const logger = (0, util_1.makeLogger)('BatchWarmingTransport');
8
34
  /**
9
35
  * Transport implementation that takes incoming batches requests and keeps a warm cache of values.
@@ -43,12 +69,14 @@ class BatchWarmingTransport {
43
69
  logger.debug('No entries in batch warming set, skipping');
44
70
  if (this.WARMER_ACTIVE) {
45
71
  // Decrement count when warmer changed from having entries to having none
72
+ cacheMetrics.cacheWarmerCount.labels({ isBatched: 'true' }).dec();
46
73
  this.WARMER_ACTIVE = false;
47
74
  }
48
75
  return this.rateLimiter.msUntilNextExecution(context.adapterEndpoint.name);
49
76
  }
50
77
  else if (this.WARMER_ACTIVE === false) {
51
78
  // Increment count when warmer changed from having no entries to having some
79
+ cacheMetrics.cacheWarmerCount.labels({ isBatched: 'true' }).inc();
52
80
  this.WARMER_ACTIVE = true;
53
81
  }
54
82
  const request = this.config.prepareRequest(entries, context);
@@ -59,6 +87,14 @@ class BatchWarmingTransport {
59
87
  const adapterResponses = (0, _1.buildCacheEntriesFromResults)(results, context);
60
88
  logger.debug('Setting adapter responses in cache');
61
89
  await this.cache.setMany(adapterResponses, context.adapterConfig.CACHE_MAX_AGE);
90
+ // Record cost of data provider call
91
+ const cost = rateLimitMetrics.retrieveCost(providerResponse.data);
92
+ rateLimitMetrics.rateLimitCreditsSpentTotal
93
+ .labels({
94
+ feed_id: 'N/A',
95
+ participant_id: WARMUP_BATCH_REQUEST_ID,
96
+ })
97
+ .inc(cost);
62
98
  return this.rateLimiter.msUntilNextExecution(context.adapterEndpoint.name);
63
99
  }
64
100
  }
@@ -1,9 +1,33 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  Object.defineProperty(exports, "__esModule", { value: true });
3
26
  exports.RestTransport = void 0;
4
27
  const util_1 = require("../util");
5
28
  const error_1 = require("../validation/error");
6
29
  const util_2 = require("./util");
30
+ const rateLimitMetrics = __importStar(require("../rate-limiting/metrics"));
7
31
  const IN_FLIGHT_PREFIX = 'InFlight';
8
32
  const logger = (0, util_1.makeLogger)('RestTransport');
9
33
  /**
@@ -90,6 +114,14 @@ class RestTransport {
90
114
  }
91
115
  logger.debug('Setting provider response in cache');
92
116
  await this.cache.set(req.requestContext.cacheKey, parsedResponse, config.CACHE_MAX_AGE);
117
+ // Record cost of data provider call
118
+ const cost = rateLimitMetrics.retrieveCost(providerResponse.data);
119
+ rateLimitMetrics.rateLimitCreditsSpentTotal
120
+ .labels({
121
+ feed_id: req.requestContext.meta?.metrics?.feedId || 'N/A',
122
+ participant_id: req.requestContext.cacheKey,
123
+ })
124
+ .inc(cost);
93
125
  // Update cacheHit flag in request meta for metrics use
94
126
  req.requestContext.meta = {
95
127
  ...req.requestContext.meta,
@@ -1,4 +1,27 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
@@ -6,6 +29,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
29
  exports.axiosRequest = void 0;
7
30
  const axios_1 = __importDefault(require("axios"));
8
31
  const error_1 = require("../validation/error");
32
+ const transportMetrics = __importStar(require("./metrics"));
9
33
  /**
10
34
  * Performs axios request along with metrics recording and error handling
11
35
  *
@@ -13,6 +37,7 @@ const error_1 = require("../validation/error");
13
37
  * @returns axios response for the request
14
38
  */
15
39
  async function axiosRequest(request, config) {
40
+ const responseTimer = transportMetrics.dataProviderRequestDurationSeconds.startTimer();
16
41
  let providerResponse;
17
42
  try {
18
43
  request.timeout = config.API_TIMEOUT;
@@ -37,6 +62,9 @@ async function axiosRequest(request, config) {
37
62
  providerStatusCode = 0; // 0 -> connection error
38
63
  }
39
64
  // Record count of failed data provider request
65
+ transportMetrics.dataProviderRequests
66
+ .labels(transportMetrics.dataProviderMetricsLabel(providerStatusCode, request.method))
67
+ .inc();
40
68
  adapterError.statusCode = 200;
41
69
  adapterError.providerStatusCode = providerStatusCode;
42
70
  adapterError.message = error?.message;
@@ -47,7 +75,12 @@ async function axiosRequest(request, config) {
47
75
  }
48
76
  finally {
49
77
  // Record time taken for data provider request for success or failure
78
+ responseTimer();
50
79
  }
80
+ // Record count of successful data provider requests
81
+ transportMetrics.dataProviderRequests
82
+ .labels(transportMetrics.dataProviderMetricsLabel(providerResponse.status, request.method))
83
+ .inc();
51
84
  return providerResponse;
52
85
  }
53
86
  exports.axiosRequest = axiosRequest;
@@ -1,4 +1,27 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
@@ -7,6 +30,7 @@ exports.WebSocketTransport = exports.WebSocketClassProvider = void 0;
7
30
  const ws_1 = __importDefault(require("ws"));
8
31
  const util_1 = require("../util");
9
32
  const _1 = require("./");
33
+ const transportMetrics = __importStar(require("./metrics"));
10
34
  const logger = (0, util_1.makeLogger)('WebSocketTransport');
11
35
  class WebSocketClassProvider {
12
36
  static set(ctor) {
@@ -63,6 +87,7 @@ class WebSocketTransport {
63
87
  logger.debug('Successfully executed connection opened handler');
64
88
  // Record active ws connections by incrementing count on open
65
89
  // Using URL in label since connection_key is removed from v3
90
+ transportMetrics.wsConnectionActive.inc();
66
91
  resolve(true);
67
92
  });
68
93
  this.wsConnection.addEventListener('message', async (event) => {
@@ -78,11 +103,15 @@ class WebSocketTransport {
78
103
  });
79
104
  this.wsConnection.addEventListener('error', async (event) => {
80
105
  // Record connection error count
106
+ transportMetrics.wsConnectionErrors
107
+ .labels(transportMetrics.connectionErrorLabels(event.message))
108
+ .inc();
81
109
  });
82
110
  this.wsConnection.addEventListener('close', (event) => {
83
111
  logger.debug(`Closed websocket connection. Code: ${event.code} ; reason: ${event.reason?.toString()}`);
84
112
  // Record active ws connections by decrementing count on close
85
113
  // Using URL in label since connection_key is removed from v3
114
+ transportMetrics.wsConnectionActive.dec();
86
115
  });
87
116
  });
88
117
  }
@@ -126,6 +155,8 @@ class WebSocketTransport {
126
155
  logger.trace(`Sending message: ${JSON.stringify(message)}`);
127
156
  this.wsConnection.send(message);
128
157
  }
158
+ // Record WS message and subscription metrics
159
+ transportMetrics.recordWsMessageMetrics(context, subscribeParams, unsubscribeParams);
129
160
  logger.debug('Setting local state to cache value');
130
161
  this.localSubscriptions = desiredSubs;
131
162
  logger.debug('Background execute complete');
package/adapter.d.ts DELETED
@@ -1,139 +0,0 @@
1
- import { Cache } from './cache';
2
- import { AdapterConfig, BaseAdapterConfig, CustomSettingsType, SettingsMap } from './config';
3
- import { AdapterRateLimitTier, BackgroundExecuteRateLimiter, RequestRateLimiter } from './rate-limiting';
4
- import { Transport } from './transports';
5
- import { SubscriptionSetFactory } from './util';
6
- import { InputParameters } from './validation/input-params';
7
- /**
8
- * Dependencies that will be injected into the Adapter on startup
9
- */
10
- export interface AdapterDependencies {
11
- /** Specific instance of the Cache the adapter will use (e.g. Local, Redis, etc.) */
12
- cache: Cache;
13
- /** Shared instance of the request rate limiter */
14
- requestRateLimiter: RequestRateLimiter;
15
- /** Shared instance of the background execute rate limiter */
16
- backgroundExecuteRateLimiter: BackgroundExecuteRateLimiter;
17
- /** Factory to create subscription sets based on the specified cache type */
18
- subscriptionSetFactory: SubscriptionSetFactory;
19
- }
20
- /**
21
- * Context that will be used on background executions of a Transport.
22
- * For example, the endpointName used to log statements or generate Cache keys.
23
- */
24
- export interface AdapterContext<CustomSettings extends CustomSettingsType<CustomSettings> = SettingsMap> {
25
- /** Endpoint instance within the adapter that the Transport is related to */
26
- adapterEndpoint: AdapterEndpoint<unknown, unknown, CustomSettings>;
27
- /** Initialized config for the adapter that the Transport can access */
28
- adapterConfig: AdapterConfig<CustomSettings>;
29
- }
30
- /**
31
- * Structure to describe rate limits specs for the Adapter
32
- */
33
- interface AdapterRateLimitingConfig {
34
- /** Adapter rate limits, gotten from the specific tier requested */
35
- tiers: Record<string, AdapterRateLimitTier>;
36
- }
37
- /**
38
- * Main structure of an External Adapter
39
- */
40
- export interface AdapterParams<CustomSettings extends SettingsMap> {
41
- /** Name of the adapter */
42
- name: string;
43
- /** If present, the string that will be used for requests with no specified endpoint */
44
- defaultEndpoint?: string;
45
- /**
46
- * List of [[AdapterEndpoint]]s in the adapter. This is purposefully typed any; it's the correct type in this case.
47
- *
48
- * When you try to create an adapter and you provide an endpoint, if these generics were set to "unknown" instead
49
- * what would happen is that Typescript would check if the types match, and would fail to assign unknown to the
50
- * specific Params or Result in the transport itself.
51
- * We also can't use generics, because if we had more than one transport with different requests (very likely)
52
- * then those new types wouldn't match with each other.
53
- */
54
- endpoints: AdapterEndpoint<any, any, CustomSettings>[];
55
- /** Map of overrides to the default config values for an Adapter */
56
- envDefaultOverrides?: Partial<BaseAdapterConfig>;
57
- /** List of custom env vars for this particular adapter (e.g. RPC_URL) */
58
- customSettings?: SettingsMap;
59
- /** Configuration relevant to outbound (EA --\> DP) communication rate limiting */
60
- rateLimiting?: AdapterRateLimitingConfig;
61
- /** Overrides for converting the 'base' parameter that are hardcoded into the adapter. */
62
- overrides?: Record<string, string>;
63
- }
64
- /**
65
- * Structure to describe rate limits specs for a specific adapter endpoint
66
- */
67
- export interface EndpointRateLimitingConfig {
68
- /**
69
- * How much of the total limit for the adapter will be assigned to this specific endpoint.
70
- * Should be a non-zero positive number up to 100.
71
- * Endpoints in the same adapter without a specific allocation will divide the remaining limits equally.
72
- */
73
- allocationPercentage: number;
74
- }
75
- /**
76
- * Structure to describe a specific endpoint in an [[Adapter]]
77
- */
78
- export interface AdapterEndpointParams<Params, Result, CustomSettings extends SettingsMap> {
79
- /** Name that will be used to match input params to this endpoint (case insensitive) */
80
- name: string;
81
- /** List of alternative endpoint names that will resolve to this same transport (case insensitive) */
82
- aliases?: string[];
83
- /** Transport that will be used to handle data processing and communication for this endpoint */
84
- transport: Transport<Params, Result, CustomSettings>;
85
- /** Specification of what the body of a request hitting this endpoint should look like (used for validation) */
86
- inputParameters: InputParameters;
87
- /** Specific details related to the rate limiting for this endpoint in particular */
88
- rateLimiting?: EndpointRateLimitingConfig;
89
- }
90
- export declare class AdapterEndpoint<Params, Result, CustomSettings extends SettingsMap> implements AdapterEndpointParams<Params, Result, CustomSettings> {
91
- name: string;
92
- aliases?: string[] | undefined;
93
- transport: Transport<Params, Result, CustomSettings>;
94
- inputParameters: InputParameters;
95
- rateLimiting?: EndpointRateLimitingConfig | undefined;
96
- constructor(params: AdapterEndpointParams<Params, Result, CustomSettings>);
97
- }
98
- export declare class Adapter<CustomSettings extends SettingsMap = SettingsMap> implements AdapterParams<CustomSettings> {
99
- name: string;
100
- defaultEndpoint?: string | undefined;
101
- endpoints: AdapterEndpoint<unknown, unknown, CustomSettings>[];
102
- envDefaultOverrides?: Partial<BaseAdapterConfig> | undefined;
103
- customSettings?: SettingsMap | undefined;
104
- rateLimiting?: AdapterRateLimitingConfig | undefined;
105
- overrides?: Record<string, string> | undefined;
106
- initialized: boolean;
107
- /** Object containing alias translations for all endpoints */
108
- endpointsMap: Record<string, AdapterEndpoint<unknown, unknown, CustomSettings>>;
109
- /** Initialized dependencies that the adapter will use */
110
- dependencies: AdapterDependencies;
111
- /** Configuration params for various adapter properties */
112
- config: AdapterConfig;
113
- constructor(params: AdapterParams<CustomSettings>);
114
- /**
115
- * Initializes all of the [[Transport]]s in the adapter, passing along any [[AdapterDependencies]] and [[AdapterConfig]].
116
- * Additionally, it builds a map out of all the endpoint names and aliases (checking for duplicates).
117
- */
118
- initialize(dependencies?: Partial<AdapterDependencies>): Promise<void>;
119
- /**
120
- * Takes an adapter and normalizes all endpoint names and aliases, as well as the default endpoint.
121
- * i.e. makes them lowercase for now
122
- */
123
- private normalizeEndpointNames;
124
- /**
125
- * This function will take an adapter structure and go through each endpoint, calculating
126
- * each one's allocation of the total rate limits that are set for the adapter as a whole.
127
- *
128
- */
129
- private calculateRateLimitAllocations;
130
- /**
131
- * This function will process dependencies for an adapter, such as caches or rate limiters,
132
- * in order to inject them into transports and other relevant places later in the lifecycle.
133
- *
134
- * @param inputDependencies - a partial obj of initialized dependencies to override the created ones
135
- * @returns a set of AdapterDependencies all initialized
136
- */
137
- initializeDependencies(inputDependencies?: Partial<AdapterDependencies>): AdapterDependencies;
138
- }
139
- export {};
@@ -1,9 +0,0 @@
1
- import { Adapter } from './adapter';
2
- /**
3
- * Very simple background loop that will call the [[Transport.backgroundExecute]] functions in all Transports.
4
- * It gets the time in ms to wait as the return value from those functions, and sleeps until next execution.
5
- *
6
- * @param adapter - an initialized External Adapter
7
- * @param server - the http server to attach an on close listener to
8
- */
9
- export declare function callBackgroundExecutes(adapter: Adapter, apiShutdownPromise?: Promise<void>): Promise<void>;
@@ -1,6 +0,0 @@
1
- import { AdapterConfig } from '../config';
2
- import { LocalCache } from './local';
3
- import { RedisCache } from './redis';
4
- export declare class CacheFactory {
5
- static buildCache(config: AdapterConfig): LocalCache<unknown> | RedisCache<unknown> | undefined;
6
- }