@chainlink/external-adapter-framework 0.0.5 → 0.0.7

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 (161) hide show
  1. package/dist/adapter.js +60 -0
  2. package/dist/background-executor.js +45 -0
  3. package/dist/cache/factory.js +57 -0
  4. package/dist/cache/index.js +163 -0
  5. package/dist/cache/local.js +83 -0
  6. package/dist/cache/metrics.js +114 -0
  7. package/dist/cache/redis.js +100 -0
  8. package/dist/config/index.js +364 -0
  9. package/dist/config/provider-limits.js +75 -0
  10. package/dist/examples/coingecko/batch-warming.js +52 -0
  11. package/dist/examples/coingecko/index.js +10 -0
  12. package/dist/examples/coingecko/rest.js +50 -0
  13. package/dist/examples/ncfx/config/index.js +15 -0
  14. package/dist/examples/ncfx/index.js +10 -0
  15. package/dist/examples/ncfx/websocket.js +72 -0
  16. package/dist/index.js +89 -0
  17. package/dist/metrics/constants.js +25 -0
  18. package/dist/metrics/index.js +76 -0
  19. package/dist/metrics/util.js +9 -0
  20. package/dist/rate-limiting/factory.js +33 -0
  21. package/dist/rate-limiting/index.js +36 -0
  22. package/dist/rate-limiting/metrics.js +32 -0
  23. package/dist/rate-limiting/nop-limiter.js +15 -0
  24. package/dist/rate-limiting/simple-counting.js +61 -0
  25. package/dist/src/adapter.js +112 -0
  26. package/dist/src/background-executor.js +45 -0
  27. package/dist/src/cache/factory.js +57 -0
  28. package/dist/src/cache/index.js +165 -0
  29. package/dist/src/cache/local.js +83 -0
  30. package/dist/src/cache/metrics.js +114 -0
  31. package/dist/src/cache/redis.js +100 -0
  32. package/dist/src/config/index.js +366 -0
  33. package/dist/src/config/provider-limits.js +75 -0
  34. package/dist/src/examples/bank-frick/accounts.js +191 -0
  35. package/dist/src/examples/bank-frick/config/index.js +45 -0
  36. package/dist/src/examples/bank-frick/index.js +14 -0
  37. package/dist/src/examples/bank-frick/util.js +39 -0
  38. package/dist/src/examples/coingecko/batch-warming.js +52 -0
  39. package/dist/src/examples/coingecko/index.js +10 -0
  40. package/dist/src/examples/coingecko/rest.js +50 -0
  41. package/dist/src/examples/ncfx/config/index.js +15 -0
  42. package/dist/src/examples/ncfx/index.js +10 -0
  43. package/dist/src/examples/ncfx/websocket.js +72 -0
  44. package/dist/src/index.js +89 -0
  45. package/dist/src/metrics/constants.js +25 -0
  46. package/dist/src/metrics/index.js +76 -0
  47. package/dist/src/metrics/util.js +9 -0
  48. package/dist/src/rate-limiting/background/fixed-frequency.js +37 -0
  49. package/dist/src/rate-limiting/index.js +63 -0
  50. package/dist/src/rate-limiting/metrics.js +32 -0
  51. package/dist/src/rate-limiting/request/simple-counting.js +62 -0
  52. package/dist/src/test.js +6 -0
  53. package/dist/src/transports/batch-warming.js +55 -0
  54. package/dist/src/transports/index.js +85 -0
  55. package/dist/src/transports/metrics.js +119 -0
  56. package/dist/src/transports/rest.js +93 -0
  57. package/dist/src/transports/util.js +85 -0
  58. package/dist/src/transports/websocket.js +175 -0
  59. package/dist/src/util/expiring-sorted-set.js +47 -0
  60. package/dist/src/util/index.js +35 -0
  61. package/dist/src/util/logger.js +62 -0
  62. package/dist/src/util/request.js +2 -0
  63. package/dist/src/validation/error.js +41 -0
  64. package/dist/src/validation/index.js +84 -0
  65. package/dist/src/validation/input-params.js +30 -0
  66. package/dist/src/validation/override-functions.js +40 -0
  67. package/dist/src/validation/preset-tokens.json +23 -0
  68. package/dist/src/validation/validator.js +303 -0
  69. package/dist/test.js +6 -0
  70. package/dist/transports/batch-warming.js +57 -0
  71. package/dist/transports/index.js +76 -0
  72. package/dist/transports/metrics.js +133 -0
  73. package/dist/transports/rest.js +91 -0
  74. package/dist/transports/util.js +85 -0
  75. package/dist/transports/websocket.js +171 -0
  76. package/dist/util/expiring-sorted-set.js +47 -0
  77. package/dist/util/index.js +35 -0
  78. package/dist/util/logger.js +62 -0
  79. package/dist/util/request.js +2 -0
  80. package/dist/validation/error.js +41 -0
  81. package/dist/validation/index.js +82 -0
  82. package/dist/validation/input-params.js +30 -0
  83. package/dist/validation/overrideFunctions.js +42 -0
  84. package/dist/validation/presetTokens.json +23 -0
  85. package/dist/validation/validator.js +303 -0
  86. package/package.json +6 -2
  87. package/.c8rc.json +0 -3
  88. package/.eslintignore +0 -9
  89. package/.eslintrc.js +0 -96
  90. package/.github/README.MD +0 -17
  91. package/.github/actions/setup/action.yaml +0 -13
  92. package/.github/workflows/main.yaml +0 -39
  93. package/.github/workflows/publish.yaml +0 -18
  94. package/.prettierignore +0 -13
  95. package/.yarnrc +0 -0
  96. package/docker-compose.yaml +0 -35
  97. package/src/adapter.ts +0 -236
  98. package/src/background-executor.ts +0 -53
  99. package/src/cache/factory.ts +0 -28
  100. package/src/cache/index.ts +0 -236
  101. package/src/cache/local.ts +0 -73
  102. package/src/cache/metrics.ts +0 -112
  103. package/src/cache/redis.ts +0 -93
  104. package/src/config/index.ts +0 -501
  105. package/src/config/provider-limits.ts +0 -130
  106. package/src/examples/coingecko/batch-warming.ts +0 -79
  107. package/src/examples/coingecko/index.ts +0 -9
  108. package/src/examples/coingecko/rest.ts +0 -77
  109. package/src/examples/ncfx/config/index.ts +0 -12
  110. package/src/examples/ncfx/index.ts +0 -9
  111. package/src/examples/ncfx/websocket.ts +0 -100
  112. package/src/index.ts +0 -106
  113. package/src/metrics/constants.ts +0 -23
  114. package/src/metrics/index.ts +0 -116
  115. package/src/metrics/util.ts +0 -11
  116. package/src/rate-limiting/background/fixed-frequency.ts +0 -47
  117. package/src/rate-limiting/index.ts +0 -100
  118. package/src/rate-limiting/metrics.ts +0 -18
  119. package/src/rate-limiting/request/simple-counting.ts +0 -76
  120. package/src/test.ts +0 -5
  121. package/src/transports/batch-warming.ts +0 -121
  122. package/src/transports/index.ts +0 -173
  123. package/src/transports/metrics.ts +0 -95
  124. package/src/transports/rest.ts +0 -161
  125. package/src/transports/util.ts +0 -63
  126. package/src/transports/websocket.ts +0 -238
  127. package/src/util/expiring-sorted-set.ts +0 -52
  128. package/src/util/index.ts +0 -20
  129. package/src/util/logger.ts +0 -69
  130. package/src/util/request.ts +0 -115
  131. package/src/validation/error.ts +0 -116
  132. package/src/validation/index.ts +0 -101
  133. package/src/validation/input-params.ts +0 -45
  134. package/src/validation/override-functions.ts +0 -44
  135. package/src/validation/preset-tokens.json +0 -23
  136. package/src/validation/validator.ts +0 -384
  137. package/test/adapter.test.ts +0 -27
  138. package/test/background-executor.test.ts +0 -109
  139. package/test/cache/cache-key.test.ts +0 -96
  140. package/test/cache/helper.ts +0 -101
  141. package/test/cache/local.test.ts +0 -54
  142. package/test/cache/redis.test.ts +0 -89
  143. package/test/correlation.test.ts +0 -114
  144. package/test/index.test.ts +0 -37
  145. package/test/metrics/feed-id.test.ts +0 -33
  146. package/test/metrics/helper.ts +0 -14
  147. package/test/metrics/labels.test.ts +0 -36
  148. package/test/metrics/metrics.test.ts +0 -267
  149. package/test/metrics/redis-metrics.test.ts +0 -113
  150. package/test/metrics/warmer-metrics.test.ts +0 -192
  151. package/test/metrics/ws-metrics.test.ts +0 -225
  152. package/test/rate-limit-config.test.ts +0 -243
  153. package/test/transports/batch.test.ts +0 -465
  154. package/test/transports/rest.test.ts +0 -242
  155. package/test/transports/websocket.test.ts +0 -183
  156. package/test/tsconfig.json +0 -5
  157. package/test/util.ts +0 -76
  158. package/test/validation.test.ts +0 -169
  159. package/test.sh +0 -20
  160. package/tsconfig.json +0 -24
  161. package/typedoc.json +0 -6
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,18 +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
- # - main
9
- jobs:
10
- publish: # Load the dependencies cache for all jobs
11
- runs-on: ubuntu-latest
12
- environment: main
13
- steps:
14
- - uses: actions/checkout@v3
15
- - uses: ./.github/actions/setup
16
- - 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
17
- env:
18
- 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
@@ -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
package/src/adapter.ts DELETED
@@ -1,236 +0,0 @@
1
- import { CacheFactory } from './cache/factory'
2
- import { AdapterConfig, BaseAdapterConfig, SettingsMap } from './config'
3
- import {
4
- AdapterRateLimitTier,
5
- FixedFrequencyRateLimiter,
6
- getRateLimitingTier,
7
- SimpleCountingRateLimiter,
8
- } from './rate-limiting'
9
- import { AdapterDependencies, Transport } from './transports'
10
- import { makeLogger } from './util'
11
- import { InputParameters } from './validation/input-params'
12
-
13
- const logger = makeLogger('Adapter')
14
-
15
- /**
16
- * Structure to describe rate limits specs for the Adapter
17
- */
18
- interface AdapterRateLimitingConfig {
19
- /** Adapter rate limits, gotten from the specific tier requested */
20
- tiers: Record<string, AdapterRateLimitTier>
21
- }
22
-
23
- /**
24
- * Main structure of an External Adapter
25
- */
26
- export interface Adapter {
27
- /** Name of the adapter */
28
- name: string
29
-
30
- /** If present, the string that will be used for requests with no specified endpoint */
31
- defaultEndpoint?: string
32
-
33
- /** List of [[AdapterEndpoint]]s in the adapter */
34
- endpoints: AdapterEndpoint[]
35
-
36
- /** Map of overrides to the default config values for an Adapter */
37
- envDefaultOverrides?: Partial<BaseAdapterConfig>
38
-
39
- /** List of custom env vars for this particular adapter (e.g. RPC_URL) */
40
- customSettings?: SettingsMap
41
-
42
- /** Configuration relevant to outbound (EA --\> DP) communication rate limiting */
43
- rateLimiting?: AdapterRateLimitingConfig
44
-
45
- /** Overrides for converting the 'base' parameter that are hardcoded into the adapter. */
46
- // This must be included in the middleware in order to generate deterministing cache keys for hardcoded overrides
47
- overrides?: Record<string, string>
48
- }
49
-
50
- /**
51
- * Structure to describe rate limits specs for a specific adapter endpoint
52
- */
53
- export interface EndpointRateLimitingConfig {
54
- /**
55
- * How much of the total limit for the adapter will be assigned to this specific endpoint.
56
- * Should be a non-zero positive number up to 100.
57
- * Endpoints in the same adapter without a specific allocation will divide the remaining limits equally.
58
- */
59
- allocationPercentage: number
60
- }
61
-
62
- /**
63
- * Structure to describe a specific endpoint in an [[Adapter]]
64
- */
65
- export interface AdapterEndpoint {
66
- /** Name that will be used to match input params to this endpoint (case insensitive) */
67
- name: string
68
-
69
- /** List of alternative endpoint names that will resolve to this same transport (case insensitive) */
70
- aliases?: string[]
71
-
72
- /** Transport that will be used to handle data processing and communication for this endpoint */
73
- transport: Transport<any, any, any>
74
-
75
- /** Specification of what the body of a request hitting this endpoint should look like (used for validation) */
76
- inputParameters: InputParameters
77
-
78
- /** Specific details related to the rate limiting for this endpoint in particular */
79
- rateLimiting?: EndpointRateLimitingConfig
80
- }
81
-
82
- /**
83
- * Structure to describe an adapter that has been initialized
84
- */
85
- export interface InitializedAdapter extends Adapter {
86
- /** Object containing alias translations for all endpoints */
87
- endpointsMap: Record<string, AdapterEndpoint>
88
-
89
- /** Initialized dependencies that the adapter will use */
90
- dependencies: AdapterDependencies
91
-
92
- /** Configuration params for various adapter properties */
93
- config: AdapterConfig
94
- }
95
-
96
- /**
97
- * This function will take an adapter structure and go through each endpoint, calculating
98
- * each one's allocation of the total rate limits that are set for the adapter as a whole.
99
- *
100
- * @param adapter - the adapter to initialize rate limiting for
101
- */
102
- const calculateRateLimitAllocations = (adapter: Adapter) => {
103
- const numberOfEndpoints = adapter.endpoints.length
104
- const endpointsWithExplicitAllocations = adapter.endpoints.filter((e) => e.rateLimiting)
105
-
106
- const totalExplicitAllocation = endpointsWithExplicitAllocations
107
- .map((e) => e.rateLimiting?.allocationPercentage || 0)
108
- .reduce((sum, next) => sum + next, 0)
109
-
110
- if (totalExplicitAllocation > 100) {
111
- throw new Error('The total allocation set for all endpoints summed cannot exceed 100%')
112
- }
113
-
114
- if (
115
- totalExplicitAllocation === 100 &&
116
- numberOfEndpoints - endpointsWithExplicitAllocations.length > 0
117
- ) {
118
- throw new Error(
119
- 'The explicit allocation is at 100% but there are endpoints with implicit allocation',
120
- )
121
- }
122
-
123
- const implicitAllocation = 100 - totalExplicitAllocation
124
-
125
- logger.debug('Adapter rate limit allocations:')
126
- for (const endpoint of adapter.endpoints) {
127
- if (!endpoint.rateLimiting) {
128
- endpoint.rateLimiting = {
129
- allocationPercentage:
130
- implicitAllocation / (numberOfEndpoints - endpointsWithExplicitAllocations.length),
131
- }
132
- }
133
-
134
- logger.debug(`Endpoint [${endpoint.name}] - ${endpoint.rateLimiting?.allocationPercentage}%`)
135
- }
136
- }
137
-
138
- /**
139
- * This function will process dependencies for an adapter, such as caches or rate limiters,
140
- * in order to inject them into transports and other relevant places later in the lifecycle.
141
- *
142
- * @param config - the configuration for this adapter
143
- * @param inputDependencies - a partial obj of initialized dependencies to override the created ones
144
- * @param rateLimitingConfig - details from the adapter regarding rate limiting
145
- * @returns a set of AdapterDependencies all initialized
146
- */
147
- export const initializeDependencies = (
148
- adapter: Adapter,
149
- config: AdapterConfig,
150
- inputDependencies?: Partial<AdapterDependencies>,
151
- ): AdapterDependencies => {
152
- const dependencies = inputDependencies || {}
153
- if (!dependencies.cache) {
154
- dependencies.cache = CacheFactory.buildCache(config)
155
- }
156
-
157
- // In the future we might want something more complex, but for now it's better to simplify
158
- // and just use the same rate limiting for everything. Once we have a more complex use case we
159
- // can think of ways to make this more configurable.
160
- const rateLimitingTier = getRateLimitingTier(
161
- adapter.rateLimiting?.tiers,
162
- config.RATE_LIMIT_API_TIER,
163
- )
164
- if (!dependencies.requestRateLimiter) {
165
- dependencies.requestRateLimiter = new SimpleCountingRateLimiter().initialize(
166
- adapter.endpoints,
167
- rateLimitingTier,
168
- )
169
- }
170
- if (!dependencies.backgroundExecuteRateLimiter) {
171
- dependencies.backgroundExecuteRateLimiter = new FixedFrequencyRateLimiter().initialize(
172
- adapter.endpoints,
173
- rateLimitingTier,
174
- )
175
- }
176
-
177
- return dependencies as AdapterDependencies
178
- }
179
-
180
- /**
181
- * Takes an adapter and normalizes all endpoint names and aliases, as well as the default endpoint.
182
- * i.e. makes them lowercase for now
183
- * @param adapter - an instance of an Adapter
184
- */
185
- const normalizeEndpointNames = (adapter: Adapter) => {
186
- // Make endpoints case insensitive, including default
187
- adapter.defaultEndpoint = adapter.defaultEndpoint?.toLowerCase()
188
-
189
- for (const endpoint of adapter.endpoints) {
190
- endpoint.name = endpoint.name.toLowerCase()
191
- endpoint.aliases = endpoint.aliases?.map((a) => a.toLowerCase())
192
- }
193
- }
194
-
195
- /**
196
- * Initializes all of the [[Transport]]s in the adapter, passing along any [[AdapterDependencies]] and [[AdapterConfig]].
197
- * Additionally, it builds a map out of all the endpoint names and aliases (checking for duplicates).
198
- *
199
- * @param adapter - an instance of an Adapter
200
- * @param dependencies - dependencies that the adapter will need at initialization
201
- * @param config - configuration variables already processed and validated
202
- * @returns - the adapter with all transports initialized and aliases map built
203
- */
204
- export const initializeAdapter = async (
205
- adapter: Adapter,
206
- config: AdapterConfig,
207
- dependencies?: Partial<AdapterDependencies>,
208
- ): Promise<InitializedAdapter> => {
209
- normalizeEndpointNames(adapter)
210
- calculateRateLimitAllocations(adapter)
211
- const initializedDependencies = initializeDependencies(adapter, config, dependencies)
212
-
213
- const endpointsMap: Record<string, AdapterEndpoint> = {}
214
-
215
- for (const endpoint of adapter.endpoints) {
216
- // Add aliases to map to use in validation
217
- const aliases = [endpoint.name, ...(endpoint.aliases || [])]
218
- for (const alias of aliases) {
219
- if (endpointsMap[alias]) {
220
- throw new Error(`Duplicate endpoint / alias: "${alias}"`)
221
- }
222
- endpointsMap[alias] = endpoint
223
- }
224
-
225
- logger.debug(`Initializing transport for endpoint "${endpoint.name}"...`)
226
- await endpoint.transport.initialize(initializedDependencies)
227
- }
228
-
229
- logger.debug('Adapter initialization complete.')
230
- return {
231
- ...adapter,
232
- endpointsMap,
233
- dependencies: initializedDependencies,
234
- config,
235
- }
236
- }
@@ -1,53 +0,0 @@
1
- import { Server } from 'http'
2
- import { InitializedAdapter } from './adapter'
3
- import { AdapterContext } from './transports'
4
- import { makeLogger, sleep } from './util'
5
-
6
- const logger = makeLogger('BackgroundExecutor')
7
-
8
- /**
9
- * Very simple background loop that will call the [[Transport.backgroundExecute]] functions in all Transports.
10
- * It gets the time in ms to wait as the return value from those functions, and sleeps until next execution.
11
- *
12
- * @param adapter - an initialized External Adapter
13
- * @param server - the http server to attach an on close listener to
14
- */
15
- export async function callBackgroundExecutes(adapter: InitializedAdapter, server?: Server) {
16
- // Set up variable to check later on to see if we need to stop this background "thread"
17
- // If no server is provided, the listener won't be set and serverClosed will always be false
18
- let serverClosed = false
19
- server?.on('close', () => {
20
- serverClosed = true
21
- })
22
-
23
- for (const endpoint of adapter.endpoints) {
24
- const backgroundExecute = endpoint.transport.backgroundExecute?.bind(endpoint.transport)
25
- if (!backgroundExecute) {
26
- logger.debug(`Endpoint "${endpoint.name}" has no background execute, skipping...`)
27
- continue
28
- }
29
-
30
- const context: AdapterContext = {
31
- adapterEndpoint: endpoint,
32
- adapterConfig: adapter.config,
33
- }
34
-
35
- const handler = async () => {
36
- if (serverClosed) {
37
- logger.info('Server closed, stopping recursive backgroundExecute handler chain')
38
- return
39
- }
40
-
41
- logger.debug(`Calling background execute for endpoint "${endpoint.name}"`)
42
- const timeToWait = await backgroundExecute(context)
43
- logger.debug(
44
- `Finished background execute for endpoint "${endpoint.name}", sleeping for ${timeToWait}ms`,
45
- )
46
- await sleep(timeToWait)
47
- handler()
48
- }
49
-
50
- // Start recursive async calls
51
- handler()
52
- }
53
- }
@@ -1,28 +0,0 @@
1
- import Redis from 'ioredis'
2
- import { AdapterConfig } from '../config'
3
- import { makeLogger } from '../util'
4
- import { LocalCache } from './local'
5
- import * as cacheMetrics from './metrics'
6
- import { RedisCache } from './redis'
7
-
8
- const logger = makeLogger('CacheFactory')
9
- export class CacheFactory {
10
- static buildCache(config: AdapterConfig) {
11
- logger.info(`Using "${config.CACHE_TYPE}" cache.`)
12
- if (config.CACHE_TYPE === 'local') {
13
- return new LocalCache()
14
- } else if (config.CACHE_TYPE === 'redis') {
15
- const redis = new Redis({
16
- enableAutoPipelining: true, // This will make multiple commands be batch automatically
17
- host: config.CACHE_REDIS_HOST,
18
- port: config.CACHE_REDIS_PORT,
19
- })
20
- redis.on('connect', () => {
21
- cacheMetrics.redisConnectionsOpen.inc()
22
- })
23
- // TODO: Maybe track active redis connections instead of just total count of connections created
24
- // Use a Gauge and track with a combo of connect/end events listeners
25
- return new RedisCache(redis)
26
- }
27
- }
28
- }