Skip to content

Commit

Permalink
[release] @subql/[email protected]
Browse files Browse the repository at this point in the history
* orderManager return runner score

* update score funcitons to use Promise

* remove commented

* [release] @subql/[email protected]
  • Loading branch information
icezohu authored Apr 8, 2024
1 parent 12362f7 commit 1b1cc00
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 65 deletions.
5 changes: 4 additions & 1 deletion packages/network-support/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion packages/network-support/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
59 changes: 22 additions & 37 deletions packages/network-support/src/orderManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[] = [];

Expand All @@ -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;
Expand Down Expand Up @@ -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<RequestParam | undefined> {
const innerRequest = async () => {
const order = await this.getNextOrder(requestId);
Expand Down Expand Up @@ -311,47 +292,47 @@ export class OrderManager {
return undefined;
}

protected async getNextAgreement(requestId: string): Promise<ServiceAgreementOrder | undefined> {
private async getNextAgreement(requestId: string): Promise<ServiceAgreementOrder | undefined> {
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<FlexPlanOrder | undefined> {
private async getNextPlan(requestId: string): Promise<FlexPlanOrder | undefined> {
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<Order | undefined> {
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}`);
Expand Down Expand Up @@ -381,14 +362,14 @@ export class OrderManager {
return res.token;
}

private getSelectedRunners(requestId: string): string[] {
private async getSelectedRunners(requestId: string): Promise<string[]> {
if (!requestId) return [];
return this.selectedRunnersStore.get<string[]>(requestId) || [];
return (await this.selectedRunnersStore.get<string[]>(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]);
}
Expand All @@ -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() {
Expand Down
21 changes: 4 additions & 17 deletions packages/network-support/src/scoreManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<number | ScoreStoreType>(key);
let score = await this.scoreStore.get<number | ScoreStoreType>(key);

if (score === undefined) {
score = {
Expand All @@ -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<number | ScoreStoreType>(key) ?? 100;
let score = (await this.scoreStore.get<number | ScoreStoreType>(key)) ?? 100;

if (typeof score === 'number') {
score = {
Expand Down
18 changes: 9 additions & 9 deletions packages/network-support/src/utils/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import { LRUCache as LRU } from 'lru-cache';

export interface IStore {
get<T>(key: string): T | undefined;
set<T>(key: string, value: T): void; // ttl in milliseconds
remove(key: string): void;
get<T>(key: string): Promise<T | undefined>;
set<T>(key: string, value: T): Promise<void>; // ttl in milliseconds
remove(key: string): Promise<void>;
}

interface Options {
Expand All @@ -20,7 +20,7 @@ export class LocalStorageCache implements IStore {
this.ttl = options.ttl;
}

get<T>(key: string): T | undefined {
async get<T>(key: string): Promise<T | undefined> {
const data = localStorage.getItem(key);
if (!data) return undefined;

Expand All @@ -37,15 +37,15 @@ export class LocalStorageCache implements IStore {
}
}

set<T>(key: string, value: T): void {
async set<T>(key: string, value: T): Promise<void> {
const data = {
value,
expiry: this.ttl ? Date.now() + this.ttl : undefined,
};
localStorage.setItem(key, JSON.stringify(data));
}

remove(key: string): void {
async remove(key: string): Promise<void> {
localStorage.removeItem(key);
}
}
Expand All @@ -57,17 +57,17 @@ export class LRUCache implements IStore {
this.cache = new LRU({ max: 1000, ttl: options.ttl });
}

get<T>(key: string): T | undefined {
async get<T>(key: string): Promise<T | undefined> {
return this.cache.get(key);
}

set<T>(key: string, value: T, ttl?: number): void {
async set<T>(key: string, value: T, ttl?: number): Promise<void> {
// 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<void> {
this.cache.delete(key);
}
}
Expand Down

0 comments on commit 1b1cc00

Please sign in to comment.