@subql/apollo-links
Advanced tools
Comparing version 1.0.0 to 1.0.1-0
@@ -55,5 +55,5 @@ "use strict"; | ||
// 4. httpLink: This should always be at the end of the link chain. This link is responsible for sending the request to the server. | ||
const link = (0, core_1.from)([errorLink, retryLink, authLink, fallbackLink, responseLink, httpLink]); | ||
const link = (0, core_1.from)([retryLink, errorLink, authLink, fallbackLink, responseLink, httpLink]); | ||
return { link, cleanup }; | ||
} | ||
//# sourceMappingURL=authHttpLink.js.map |
@@ -24,2 +24,3 @@ "use strict"; | ||
.then((params) => { | ||
var _a; | ||
if (params === null || params === void 0 ? void 0 : params.data) { | ||
@@ -29,2 +30,3 @@ const { authorization, url, type } = params.data; | ||
operation.setContext({ url, headers, type }); | ||
sub = forward(operation).subscribe(observer); | ||
} | ||
@@ -34,9 +36,9 @@ else if (params === null || params === void 0 ? void 0 : params.error) { | ||
operation.setContext({ indexer }); | ||
this.logger.warn(`Failed to get token: ${message}`); | ||
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.debug(`Failed to get token: ${message}`); | ||
observer.error(new Error('failed to get indexer request params')); | ||
} | ||
sub = forward(operation).subscribe(observer); | ||
}) | ||
.catch((error) => { | ||
this.logger.warn(`Failed to get order request params: ${error.message}`); | ||
var _a; | ||
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.debug(`Failed to get order request params: ${error.message}`); | ||
observer.error(new Error('failed to get indexer url and token')); | ||
@@ -64,2 +66,3 @@ }); | ||
async getAgreementRequestParams() { | ||
var _a, _b, _c; | ||
const nextAgreement = await this.orderManager.getNextAgreement(); | ||
@@ -73,3 +76,3 @@ if (!nextAgreement) | ||
try { | ||
this.logger.debug(`request new token for indexer ${indexer}`); | ||
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.debug(`request new token for indexer ${indexer}`); | ||
const { projectId, authUrl } = this.options; | ||
@@ -83,7 +86,7 @@ const tokenUrl = new URL('/orders/token', authUrl); | ||
this.orderManager.updateTokenById(id, res.token); | ||
this.logger.debug(`request new token for indexer ${indexer} success`); | ||
(_b = this.logger) === null || _b === void 0 ? void 0 : _b.debug(`request new token for indexer ${indexer} success`); | ||
return { data: Object.assign({ url, type }, this.tokenToAuthHeader(res.token)) }; | ||
} | ||
catch (error) { | ||
this.logger.debug(`request new token for indexer ${indexer} failed`); | ||
(_c = this.logger) === null || _c === void 0 ? void 0 : _c.debug(`request new token for indexer ${indexer} and url: ${nextAgreement.url} failed`); | ||
return { error: { indexer: nextAgreement.indexer, message: error.message } }; | ||
@@ -93,2 +96,3 @@ } | ||
async getPlanRequestParams() { | ||
var _a, _b, _c, _d; | ||
const nextPlan = await this.orderManager.getNextPlan(); | ||
@@ -100,3 +104,3 @@ if (!nextPlan) | ||
try { | ||
this.logger.debug(`request new signature for indexer ${indexer}`); | ||
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.debug(`request new signature for indexer ${indexer}`); | ||
const { projectId: deployment, authUrl } = this.options; | ||
@@ -108,9 +112,9 @@ const tokenUrl = new URL('/channel/sign', authUrl); | ||
}); | ||
this.logger.debug(`state signature: ${signedState}`); | ||
(_b = this.logger) === null || _b === void 0 ? void 0 : _b.debug(`state signature: ${signedState}`); | ||
const authorization = JSON.stringify(signedState); | ||
this.logger.debug(`request new state signature for indexer ${indexer} success`); | ||
(_c = this.logger) === null || _c === void 0 ? void 0 : _c.debug(`request new state signature for indexer ${indexer} success`); | ||
return { data: { authorization, url, type } }; | ||
} | ||
catch (error) { | ||
this.logger.debug(`request new state signature for indexer ${indexer} failed`); | ||
(_d = this.logger) === null || _d === void 0 ? void 0 : _d.debug(`request new state signature for indexer ${indexer} failed`); | ||
return { error: { indexer: nextPlan.indexer, message: error.message } }; | ||
@@ -117,0 +121,0 @@ } |
@@ -12,6 +12,5 @@ "use strict"; | ||
orderManager.updateIndexerScore(indexer, 'graphql'); | ||
logger === null || logger === void 0 ? void 0 : logger.info(`[GraphQL error]: Message: ${message}, Location: ${JSON.stringify(locations)}, Path: ${path}`); | ||
logger === null || logger === void 0 ? void 0 : logger.debug(`[GraphQL error]: Message: ${message}, Location: ${JSON.stringify(locations)}, Path: ${path}`); | ||
}); | ||
if (networkError) { | ||
orderManager.updateIndexerScore(indexer, 'network'); | ||
if (!operation.getContext().fallback) { | ||
@@ -21,3 +20,3 @@ operation.setContext({ url: undefined }); | ||
} | ||
logger === null || logger === void 0 ? void 0 : logger.info(`[Network error]: ${networkError}`); | ||
logger === null || logger === void 0 ? void 0 : logger.debug(`[Network error]: ${networkError}`); | ||
} | ||
@@ -24,0 +23,0 @@ }); |
@@ -7,8 +7,11 @@ "use strict"; | ||
const retry_1 = require("@apollo/client/link/retry"); | ||
const createRetryLink = ({ orderManager, maxRetries = 3, logger }) => new retry_1.RetryLink({ | ||
const createRetryLink = ({ orderManager, maxRetries = 5, logger }) => new retry_1.RetryLink({ | ||
attempts: function (count, operation, error) { | ||
var _a; | ||
if (count <= maxRetries) { | ||
const { indexer } = operation.getContext(); | ||
orderManager.updateIndexerScore(indexer, 'network'); | ||
if (['empty url'].includes(error === null || error === void 0 ? void 0 : error.message) || operation.getContext().fallback) { | ||
const isEmptyUrlError = (_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.includes('empty url'); | ||
const isFallback = operation.getContext().fallback; | ||
if (!indexer && (isEmptyUrlError || isFallback)) { | ||
return false; | ||
@@ -15,0 +18,0 @@ } |
@@ -22,6 +22,7 @@ "use strict"; | ||
async refreshAgreements() { | ||
var _a; | ||
try { | ||
const orders = await (0, query_1.fetchOrders)(this.authUrl, this.projectId, this.projectType); | ||
this.agreements = this.filterOrdersByScore(orders.agreements); | ||
this.plans = this.filterOrdersByScore(orders.plans); | ||
this.agreements = orders.agreements; | ||
this.plans = orders.plans; | ||
this.healthy = true; | ||
@@ -31,3 +32,3 @@ } | ||
// it seems cannot reach this code, fetchOrders already handle the errors. | ||
this.logger.error(`fetch orders failed: ${String(e)}`); | ||
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.error(`fetch orders failed: ${String(e)}`); | ||
this.healthy = false; | ||
@@ -43,5 +44,5 @@ } | ||
getIndexerScore(indexer) { | ||
var _a; | ||
var _a, _b; | ||
const key = this.getCacheKey(indexer); | ||
return ((_a = this.cache) === null || _a === void 0 ? void 0 : _a.get(key)) || 100; | ||
return (_b = (_a = this.cache) === null || _a === void 0 ? void 0 : _a.get(key)) !== null && _b !== void 0 ? _b : 100; | ||
} | ||
@@ -70,23 +71,30 @@ isIndexerSelectable(indexer) { | ||
async getNextAgreement() { | ||
var _a; | ||
var _a, _b; | ||
await this._init; | ||
if (!this.healthy || !((_a = this.agreements) === null || _a === void 0 ? void 0 : _a.length)) | ||
if (!this.agreements) | ||
return; | ||
const agreements = this.filterOrdersByScore(this.agreements); | ||
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.debug(`available agreements count: ${agreements.length}`); | ||
if (!this.healthy || !agreements.length) | ||
return; | ||
if (this.nextAgreementIndex === undefined) { | ||
this.nextAgreementIndex = this.getRandomStartIndex(this.agreements.length); | ||
this.nextAgreementIndex = this.getRandomStartIndex(agreements.length); | ||
} | ||
const agreement = this.agreements[this.nextAgreementIndex]; | ||
this.nextAgreementIndex = this.getNextOrderIndex(this.agreements.length, this.nextAgreementIndex); | ||
const agreement = agreements[this.nextAgreementIndex]; | ||
this.nextAgreementIndex = this.getNextOrderIndex(agreements.length, this.nextAgreementIndex); | ||
(_b = this.logger) === null || _b === void 0 ? void 0 : _b.debug(`next agreement: ${JSON.stringify(agreement.indexer)}`); | ||
return agreement; | ||
} | ||
async getNextPlan() { | ||
var _a; | ||
await this._init; | ||
if (!this.healthy || !((_a = this.plans) === null || _a === void 0 ? void 0 : _a.length)) | ||
if (!this.plans) | ||
return; | ||
const plans = this.filterOrdersByScore(this.plans); | ||
if (!this.healthy || !(plans === null || plans === void 0 ? void 0 : plans.length)) | ||
return; | ||
if (this.nextPlanIndex === undefined) { | ||
this.nextPlanIndex = this.getRandomStartIndex(this.plans.length); | ||
this.nextPlanIndex = this.getRandomStartIndex(plans.length); | ||
} | ||
const plan = this.plans[this.nextPlanIndex]; | ||
this.nextPlanIndex = this.getNextOrderIndex(this.plans.length, this.nextPlanIndex); | ||
const plan = plans[this.nextPlanIndex]; | ||
this.nextPlanIndex = this.getNextOrderIndex(plans.length, this.nextPlanIndex); | ||
return plan; | ||
@@ -104,13 +112,9 @@ } | ||
updateIndexerScore(indexer, errorType) { | ||
var _a; | ||
if (!this.cache) | ||
return; | ||
const key = this.getCacheKey(indexer); | ||
const score = this.cache.get(key) || 100; | ||
let newScore = score; | ||
if (errorType === 'graphql') { | ||
newScore -= 5; | ||
} | ||
else if (errorType === 'network') { | ||
newScore -= 20; | ||
} | ||
const score = (_a = this.cache.get(key)) !== null && _a !== void 0 ? _a : 100; | ||
const delta = errorType === 'graphql' ? 10 : 50; | ||
const newScore = Math.max(score - delta, 0); | ||
this.cache.set(key, newScore); | ||
@@ -117,0 +121,0 @@ } |
{ | ||
"name": "@subql/apollo-links", | ||
"version": "1.0.0", | ||
"version": "1.0.1-0", | ||
"description": "SubQuery Network - graphql links", | ||
@@ -30,3 +30,3 @@ "main": "dist/index.js", | ||
}, | ||
"stableVersion": "0.5.9-2" | ||
"stableVersion": "1.0.0" | ||
} |
@@ -7,8 +7,8 @@ // Copyright 2020-2022 SubQuery Pte Ltd authors & contributors | ||
import { | ||
ClusterAuthLink, | ||
DynamicHttpLink, | ||
FallbackLink, | ||
Options, | ||
ResponseLink, | ||
creatErrorLink, | ||
ClusterAuthLink, | ||
Options, | ||
createRetryLink, | ||
@@ -100,5 +100,5 @@ } from './core'; | ||
// 4. httpLink: This should always be at the end of the link chain. This link is responsible for sending the request to the server. | ||
const link = from([errorLink, retryLink, authLink, fallbackLink, responseLink, httpLink]); | ||
const link = from([retryLink, errorLink, authLink, fallbackLink, responseLink, httpLink]); | ||
return { link, cleanup }; | ||
} |
@@ -56,2 +56,4 @@ // Copyright 2020-2022 SubQuery Pte Ltd authors & contributors | ||
operation.setContext({ url, headers, type }); | ||
sub = forward(operation).subscribe(observer); | ||
} else if (params?.error) { | ||
@@ -61,9 +63,8 @@ const { indexer, message } = params.error; | ||
this.logger.warn(`Failed to get token: ${message}`); | ||
this.logger?.debug(`Failed to get token: ${message}`); | ||
observer.error(new Error('failed to get indexer request params')); | ||
} | ||
sub = forward(operation).subscribe(observer); | ||
}) | ||
.catch((error) => { | ||
this.logger.warn(`Failed to get order request params: ${error.message}`); | ||
this.logger?.debug(`Failed to get order request params: ${error.message}`); | ||
observer.error(new Error('failed to get indexer url and token')); | ||
@@ -102,3 +103,3 @@ }); | ||
try { | ||
this.logger.debug(`request new token for indexer ${indexer}`); | ||
this.logger?.debug(`request new token for indexer ${indexer}`); | ||
const { projectId, authUrl } = this.options; | ||
@@ -113,6 +114,8 @@ const tokenUrl = new URL('/orders/token', authUrl); | ||
this.orderManager.updateTokenById(id, res.token); | ||
this.logger.debug(`request new token for indexer ${indexer} success`); | ||
this.logger?.debug(`request new token for indexer ${indexer} success`); | ||
return { data: { url, type, ...this.tokenToAuthHeader(res.token) } }; | ||
} catch (error) { | ||
this.logger.debug(`request new token for indexer ${indexer} failed`); | ||
this.logger?.debug( | ||
`request new token for indexer ${indexer} and url: ${nextAgreement.url} failed` | ||
); | ||
return { error: { indexer: nextAgreement.indexer, message: (error as Error).message } }; | ||
@@ -130,3 +133,3 @@ } | ||
try { | ||
this.logger.debug(`request new signature for indexer ${indexer}`); | ||
this.logger?.debug(`request new signature for indexer ${indexer}`); | ||
const { projectId: deployment, authUrl } = this.options; | ||
@@ -140,9 +143,9 @@ | ||
this.logger.debug(`state signature: ${signedState}`); | ||
this.logger?.debug(`state signature: ${signedState}`); | ||
const authorization = JSON.stringify(signedState); | ||
this.logger.debug(`request new state signature for indexer ${indexer} success`); | ||
this.logger?.debug(`request new state signature for indexer ${indexer} success`); | ||
return { data: { authorization, url, type } }; | ||
} catch (error) { | ||
this.logger.debug(`request new state signature for indexer ${indexer} failed`); | ||
this.logger?.debug(`request new state signature for indexer ${indexer} failed`); | ||
return { error: { indexer: nextPlan.indexer, message: (error as Error).message } }; | ||
@@ -149,0 +152,0 @@ } |
@@ -23,3 +23,3 @@ // Copyright 2020-2022 SubQuery Pte Ltd authors & contributors | ||
orderManager.updateIndexerScore(indexer, 'graphql'); | ||
logger?.info( | ||
logger?.debug( | ||
`[GraphQL error]: Message: ${message}, Location: ${JSON.stringify( | ||
@@ -32,3 +32,2 @@ locations | ||
if (networkError) { | ||
orderManager.updateIndexerScore(indexer, 'network'); | ||
if (!operation.getContext().fallback) { | ||
@@ -41,4 +40,4 @@ operation.setContext({ url: undefined }); | ||
} | ||
logger?.info(`[Network error]: ${networkError}`); | ||
logger?.debug(`[Network error]: ${networkError}`); | ||
} | ||
}); |
@@ -15,3 +15,3 @@ // Copyright 2020-2022 SubQuery Pte Ltd authors & contributors | ||
export const createRetryLink = ({ orderManager, maxRetries = 3, logger }: RetryLinkOption) => | ||
export const createRetryLink = ({ orderManager, maxRetries = 5, logger }: RetryLinkOption) => | ||
new RetryLink({ | ||
@@ -23,3 +23,5 @@ attempts: function (count: number, operation: Operation, error: any) { | ||
if (['empty url'].includes(error?.message) || operation.getContext().fallback) { | ||
const isEmptyUrlError = error?.message?.includes('empty url'); | ||
const isFallback = operation.getContext().fallback; | ||
if (!indexer && (isEmptyUrlError || isFallback)) { | ||
return false; | ||
@@ -26,0 +28,0 @@ } |
@@ -51,8 +51,8 @@ // Copyright 2020-2022 SubQuery Pte Ltd authors & contributors | ||
const orders = await fetchOrders(this.authUrl, this.projectId, this.projectType); | ||
this.agreements = this.filterOrdersByScore(orders.agreements) as Agreement[]; | ||
this.plans = this.filterOrdersByScore(orders.plans); | ||
this.agreements = orders.agreements; | ||
this.plans = orders.plans; | ||
this.healthy = true; | ||
} catch (e) { | ||
// it seems cannot reach this code, fetchOrders already handle the errors. | ||
this.logger.error(`fetch orders failed: ${String(e)}`); | ||
this.logger?.error(`fetch orders failed: ${String(e)}`); | ||
this.healthy = false; | ||
@@ -72,3 +72,3 @@ } | ||
const key = this.getCacheKey(indexer); | ||
return this.cache?.get<number>(key) || 100; | ||
return this.cache?.get<number>(key) ?? 100; | ||
} | ||
@@ -100,14 +100,18 @@ | ||
if (!this.healthy || !this.agreements?.length) return; | ||
if (!this.agreements) return; | ||
const agreements = this.filterOrdersByScore(this.agreements) as Agreement[]; | ||
this.logger?.debug(`available agreements count: ${agreements.length}`); | ||
if (!this.healthy || !agreements.length) return; | ||
if (this.nextAgreementIndex === undefined) { | ||
this.nextAgreementIndex = this.getRandomStartIndex(this.agreements.length); | ||
this.nextAgreementIndex = this.getRandomStartIndex(agreements.length); | ||
} | ||
const agreement = this.agreements[this.nextAgreementIndex]; | ||
this.nextAgreementIndex = this.getNextOrderIndex( | ||
this.agreements.length, | ||
this.nextAgreementIndex | ||
); | ||
const agreement = agreements[this.nextAgreementIndex]; | ||
this.nextAgreementIndex = this.getNextOrderIndex(agreements.length, this.nextAgreementIndex); | ||
this.logger?.debug(`next agreement: ${JSON.stringify(agreement.indexer)}`); | ||
return agreement; | ||
@@ -119,10 +123,13 @@ } | ||
if (!this.healthy || !this.plans?.length) return; | ||
if (!this.plans) return; | ||
const plans = this.filterOrdersByScore(this.plans) as Plan[]; | ||
if (!this.healthy || !plans?.length) return; | ||
if (this.nextPlanIndex === undefined) { | ||
this.nextPlanIndex = this.getRandomStartIndex(this.plans.length); | ||
this.nextPlanIndex = this.getRandomStartIndex(plans.length); | ||
} | ||
const plan = this.plans[this.nextPlanIndex]; | ||
this.nextPlanIndex = this.getNextOrderIndex(this.plans.length, this.nextPlanIndex); | ||
const plan = plans[this.nextPlanIndex]; | ||
this.nextPlanIndex = this.getNextOrderIndex(plans.length, this.nextPlanIndex); | ||
@@ -144,10 +151,6 @@ return plan; | ||
const key = this.getCacheKey(indexer); | ||
const score = this.cache.get<number>(key) || 100; | ||
const score = this.cache.get<number>(key) ?? 100; | ||
let newScore = score; | ||
if (errorType === 'graphql') { | ||
newScore -= 5; | ||
} else if (errorType === 'network') { | ||
newScore -= 20; | ||
} | ||
const delta = errorType === 'graphql' ? 10 : 50; | ||
const newScore = Math.max(score - delta, 0); | ||
@@ -154,0 +157,0 @@ this.cache.set(key, newScore); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
204494
1926
2