From 1b1cc00ebc0e85f90716512c61bc7c73a8acce68 Mon Sep 17 00:00:00 2001 From: icezohu Date: Mon, 8 Apr 2024 09:57:27 +0800 Subject: [PATCH] [release] @subql/network-support@1.1.2 * orderManager return runner score * update score funcitons to use Promise * remove commented * [release] @subql/network-support@1.1.2 --- packages/network-support/CHANGELOG.md | 5 +- packages/network-support/package.json | 2 +- packages/network-support/src/orderManager.ts | 59 ++++++++------------ packages/network-support/src/scoreManager.ts | 21 ++----- packages/network-support/src/utils/store.ts | 18 +++--- 5 files changed, 40 insertions(+), 65 deletions(-) diff --git a/packages/network-support/CHANGELOG.md b/packages/network-support/CHANGELOG.md index 07c6f9db..403117cc 100644 --- a/packages/network-support/CHANGELOG.md +++ b/packages/network-support/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.1.2] 2024-04-08 + ## [1.1.1] 2024-03-22 ## [1.1.0] 2024-03-15 @@ -23,7 +25,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - It's a internal library. -[unreleased]: https://github.com/subquery/network-support/compare/v1.1.1...HEAD +[unreleased]: https://github.com/subquery/network-support/compare/v1.1.2...HEAD +[1.1.2]: https://github.com/subquery/network-support/releases/tag/v1.1.2 [1.1.1]: https://github.com/subquery/network-support/releases/tag/v1.1.1 [1.1.0]: https://github.com/subquery/network-support/releases/tag/v1.1.0 [1.0.0]: https://github.com/subquery/network-support/releases/tag/v1.0.0 diff --git a/packages/network-support/package.json b/packages/network-support/package.json index 4c442eaa..14d79bee 100644 --- a/packages/network-support/package.json +++ b/packages/network-support/package.json @@ -1,6 +1,6 @@ { "name": "@subql/network-support", - "version": "1.1.1", + "version": "1.1.2", "main": "dist/index.js", "author": "SubQuery Pte Limited", "license": "Apache-2.0", diff --git a/packages/network-support/src/orderManager.ts b/packages/network-support/src/orderManager.ts index 926b7684..2af90621 100644 --- a/packages/network-support/src/orderManager.ts +++ b/packages/network-support/src/orderManager.ts @@ -44,9 +44,7 @@ function tokenToAuthHeader(token: string) { export class OrderManager { private projectType: ProjectType; - private nextAgreementIndex: number | undefined; - private nextPlanIndex: number | undefined; private _agreements: ServiceAgreementOrder[] = []; private _plans: FlexPlanOrder[] = []; @@ -60,7 +58,6 @@ export class OrderManager { private apikey?: string; private projectId: string; private interval = 300_000; - private minScore = 0; private healthy = true; private selector?: RunnerSelector; private responseFormat?: ResponseFormat; @@ -156,28 +153,12 @@ export class OrderManager { } } - private getRandomStartIndex(n: number) { - return Math.floor(Math.random() * n); - } - - private getCacheKey(runner: string): string { - return `$query-score-${runner}-${this.projectId}`; - } - - private filterOrdersByScore(orders: Order[]) { - return orders.filter(({ indexer }) => this.scoreManager.getScore(indexer) > this.minScore); - } - - private filterOrdersByRequestId(requestId: string, orders: Order[]) { + private async filterOrdersByRequestId(requestId: string, orders: Order[]) { if (!requestId) return orders; - const selected = this.getSelectedRunners(requestId); + const selected = await this.getSelectedRunners(requestId); return orders.filter(({ indexer }) => !selected.includes(indexer)); } - private getNextOrderIndex(total: number, currentIndex: number) { - return currentIndex < total - 1 ? currentIndex + 1 : 0; - } - async getRequestParams(requestId: string): Promise { const innerRequest = async () => { const order = await this.getNextOrder(requestId); @@ -311,47 +292,47 @@ export class OrderManager { return undefined; } - protected async getNextAgreement(requestId: string): Promise { + private async getNextAgreement(requestId: string): Promise { await this._init; if (!this.agreements) return; - const agreements = this.filterOrdersByRequestId(requestId, this.agreements); + const agreements = await this.filterOrdersByRequestId(requestId, this.agreements); this.logger?.debug(`available agreements count: ${agreements.length}`); if (!this.healthy || !agreements.length) return; - const agreement = this.selectRunner(agreements) as ServiceAgreementOrder; + const agreement = (await this.selectRunner(agreements)) as ServiceAgreementOrder; this.logger?.debug(`next agreement: ${JSON.stringify(agreement.indexer)}`); if (agreement) { - this.updateSelectedRunner(requestId, agreement.indexer); + await this.updateSelectedRunner(requestId, agreement.indexer); } return agreement; } - protected async getNextPlan(requestId: string): Promise { + private async getNextPlan(requestId: string): Promise { await this._init; if (!this.plans) return; - const plans = this.filterOrdersByRequestId(requestId, this.plans); + const plans = await this.filterOrdersByRequestId(requestId, this.plans); if (!this.healthy || !plans?.length) return; - const plan = this.selectRunner(plans); + const plan = await this.selectRunner(plans); if (plan) { - this.updateSelectedRunner(requestId, plan.indexer); + await this.updateSelectedRunner(requestId, plan.indexer); } return plan; } - private selectRunner(orders: Order[]): Order | undefined { + private async selectRunner(orders: Order[]): Promise { if (!orders.length) return; - const scores = orders.map((o) => this.scoreManager.getScore(o.indexer)); + const scores = await Promise.all(orders.map((o) => this.scoreManager.getScore(o.indexer))); const random = Math.random() * scores.reduce((a, b) => a + b, 0); this.logger?.debug(`selectRunner: indexers: ${orders.map((o) => o.indexer)}`); this.logger?.debug(`selectRunner: scores: ${scores}`); @@ -381,14 +362,14 @@ export class OrderManager { return res.token; } - private getSelectedRunners(requestId: string): string[] { + private async getSelectedRunners(requestId: string): Promise { if (!requestId) return []; - return this.selectedRunnersStore.get(requestId) || []; + return (await this.selectedRunnersStore.get(requestId)) || []; } - private updateSelectedRunner(requestId: string, runner: string) { + private async updateSelectedRunner(requestId: string, runner: string) { if (!requestId || !runner) return; - const runners = this.getSelectedRunners(requestId) ?? []; + const runners = (await this.getSelectedRunners(requestId)) ?? []; if (runners.includes(runner)) return; this.selectedRunnersStore.set(requestId, [...runners, runner]); } @@ -401,8 +382,12 @@ export class OrderManager { this.agreements[index].token = token; } - updateScore(runner: string, errorType: ScoreType) { - this.scoreManager.updateScore(runner, errorType); + async getScore(runner: string) { + return this.scoreManager.getScore(runner); + } + + async updateScore(runner: string, errorType: ScoreType) { + await this.scoreManager.updateScore(runner, errorType); } cleanup() { diff --git a/packages/network-support/src/scoreManager.ts b/packages/network-support/src/scoreManager.ts index 7936155f..943df246 100644 --- a/packages/network-support/src/scoreManager.ts +++ b/packages/network-support/src/scoreManager.ts @@ -44,9 +44,9 @@ export class ScoreManager { this.projectId = options.projectId; } - getScore(runner: string) { + async getScore(runner: string) { const key = this.getCacheKey(runner); - let score = this.scoreStore.get(key); + let score = await this.scoreStore.get(key); if (score === undefined) { score = { @@ -65,30 +65,17 @@ export class ScoreManager { } private calculatedScore(score: ScoreStoreType) { - // if (score.lastFailed) { - // return Math.min( - // score.score + Math.floor((Date.now() - score.lastFailed) / (600_000)), - // 100 - // ); - // } - - // if (score.lastUpdate && Date.now() - score.lastUpdate < 5 * 1000) { - // return Math.max(score.score - 50, this.minScore); - // } - - // return score.score; - return Math.min(score.score + Math.floor((Date.now() - score.lastUpdate) / 600_000), 100); } - updateScore(runner: string, errorType: ScoreType) { + async updateScore(runner: string, errorType: ScoreType) { if (!runner) { this.logger?.debug('updateScore: runner is empty'); return; } const key = this.getCacheKey(runner); - let score = this.scoreStore.get(key) ?? 100; + let score = (await this.scoreStore.get(key)) ?? 100; if (typeof score === 'number') { score = { diff --git a/packages/network-support/src/utils/store.ts b/packages/network-support/src/utils/store.ts index 983c39cb..0801d14b 100644 --- a/packages/network-support/src/utils/store.ts +++ b/packages/network-support/src/utils/store.ts @@ -4,9 +4,9 @@ import { LRUCache as LRU } from 'lru-cache'; export interface IStore { - get(key: string): T | undefined; - set(key: string, value: T): void; // ttl in milliseconds - remove(key: string): void; + get(key: string): Promise; + set(key: string, value: T): Promise; // ttl in milliseconds + remove(key: string): Promise; } interface Options { @@ -20,7 +20,7 @@ export class LocalStorageCache implements IStore { this.ttl = options.ttl; } - get(key: string): T | undefined { + async get(key: string): Promise { const data = localStorage.getItem(key); if (!data) return undefined; @@ -37,7 +37,7 @@ export class LocalStorageCache implements IStore { } } - set(key: string, value: T): void { + async set(key: string, value: T): Promise { const data = { value, expiry: this.ttl ? Date.now() + this.ttl : undefined, @@ -45,7 +45,7 @@ export class LocalStorageCache implements IStore { localStorage.setItem(key, JSON.stringify(data)); } - remove(key: string): void { + async remove(key: string): Promise { localStorage.removeItem(key); } } @@ -57,17 +57,17 @@ export class LRUCache implements IStore { this.cache = new LRU({ max: 1000, ttl: options.ttl }); } - get(key: string): T | undefined { + async get(key: string): Promise { return this.cache.get(key); } - set(key: string, value: T, ttl?: number): void { + async set(key: string, value: T, ttl?: number): Promise { // If ttl is defined, it is passed in milliseconds. // lru-cache expects ttl in milliseconds as well, so it aligns perfectly. this.cache.set(key, value, { ttl }); } - remove(key: string): void { + async remove(key: string): Promise { this.cache.delete(key); } }