From e840ce1dad4bafd71d0fce2d6835c95fca736bde Mon Sep 17 00:00:00 2001 From: Yornaath Date: Mon, 22 Aug 2022 14:46:59 +0200 Subject: [PATCH] Improved connection behaviour (#212) * catch retry error * set timeout a bit higher since error treshold will catch initial retries faster. * remove unused imports * only catch retry errors on initial connection and prevent it from disconnection on subsequent errors * set timeout window to 60 sec as failing connection will be thrown earlier anyway --- packages/sdk/src/index.ts | 29 +++- packages/sdk/src/util/polkadot.ts | 241 ++++++++++++++++-------------- 2 files changed, 150 insertions(+), 120 deletions(-) diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 70c11b45..32245f01 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -3,7 +3,7 @@ import { GraphQLClient, request, gql } from "graphql-request"; import ErrorTable from "./errorTable"; import Models from "./models"; -import { initApi } from "./util"; +import { lazyInitApi } from "./util/polkadot"; export * as models from "./models"; export * as types from "./types"; @@ -13,6 +13,7 @@ type InitOptions = { logEndpointInitTime?: boolean; graphQlEndpoint?: string; ipfsClientUrl?: string; + initialConnectionTries?: number; }; export const pingGqlEndpoint = async (endpoint: string) => { @@ -60,13 +61,33 @@ export default class SDK { opts: InitOptions = { logEndpointInitTime: true, ipfsClientUrl: "https://ipfs.zeitgeist.pm", + initialConnectionTries: 5, } ): Promise { try { const start = Date.now(); - const api = await SDK.promiseWithTimeout( - 10000, - initApi(endpoint), + + const api = await SDK.promiseWithTimeout( + 60 * 1000, + new Promise(async (resolve, reject) => { + const [provider, create] = lazyInitApi(endpoint); + let finished = false; + let connectionTries = 0; + provider.on("error", () => { + if ( + !finished && + connectionTries++ > (opts.initialConnectionTries || 5) + ) { + finished = true; + provider.disconnect(); + reject("Could not connect to the node"); + } + }); + provider.on("connected", () => { + finished = true; + resolve(create()); + }); + }), "Timed out while connecting to the zeitgeist node. Check your node address." ); diff --git a/packages/sdk/src/util/polkadot.ts b/packages/sdk/src/util/polkadot.ts index 4a75603d..68ab7c77 100644 --- a/packages/sdk/src/util/polkadot.ts +++ b/packages/sdk/src/util/polkadot.ts @@ -18,128 +18,137 @@ const typesFromDefs = ( ); }; -export const initApi = ( - endpoint = "wss://bsr.zeitgeist.pm" -): Promise => { - return ApiPromise.create({ - provider: new WsProvider(endpoint), - rpc: { - predictionMarkets: { - marketOutcomeShareId: { - description: "Get the market outcome share identifier.", - params: [ - { - name: "market_id", - type: "MarketId", - }, - { - name: "outcome", - type: "u16", - }, - { - name: "at", - type: "Hash", - isOptional: true, - }, - ], - type: "Asset", - }, - }, - swaps: { - poolSharesId: { - description: "Gets the share identifier for the pool shares.", - params: [ - { - name: "pool_id", - type: "u128", - }, - { - name: "at", - type: "Hash", - isOptional: true, - }, - ], - type: "Asset", - }, - poolAccountId: { - description: "Gets the pool's account.", - params: [ - { - name: "pool_id", - type: "u128", - }, - { - name: "at", - type: "Hash", - isOptional: true, - }, - ], - type: "AccountId", - }, - getSpotPrice: { - description: "Gets the spot price for a pool's in and out assets.", - params: [ - { - name: "pool_id", - type: "u128", - }, - { - name: "asset_in", - type: "Asset", - }, - { - name: "asset_out", - type: "Asset", - }, - { - name: "at", - type: "Hash", - isOptional: true, - }, - ], - type: "SerdeWrapper", - }, - getSpotPrices: { - description: "Gets spot prices for a range of blocks", - params: [ - { - name: "pool_id", - type: "u128", - }, - { - name: "asset_in", - type: "Asset", - }, - { - name: "asset_out", - type: "Asset", - }, - { - name: "blocks", - type: "Vec", - }, - ], - type: "Vec", - }, +export const constructApiOptions = (provider: WsProvider) => ({ + provider, + rpc: { + predictionMarkets: { + marketOutcomeShareId: { + description: "Get the market outcome share identifier.", + params: [ + { + name: "market_id", + type: "MarketId", + }, + { + name: "outcome", + type: "u16", + }, + { + name: "at", + type: "Hash", + isOptional: true, + }, + ], + type: "Asset", }, }, - typesAlias: { - tokens: { - AccountData: "TokensAccountData", + swaps: { + poolSharesId: { + description: "Gets the share identifier for the pool shares.", + params: [ + { + name: "pool_id", + type: "u128", + }, + { + name: "at", + type: "Hash", + isOptional: true, + }, + ], + type: "Asset", }, - }, - types: { - ...typesFromDefs(zeitgeistDefinitions), - BalanceInfo: { - amount: "Balance", + poolAccountId: { + description: "Gets the pool's account.", + params: [ + { + name: "pool_id", + type: "u128", + }, + { + name: "at", + type: "Hash", + isOptional: true, + }, + ], + type: "AccountId", + }, + getSpotPrice: { + description: "Gets the spot price for a pool's in and out assets.", + params: [ + { + name: "pool_id", + type: "u128", + }, + { + name: "asset_in", + type: "Asset", + }, + { + name: "asset_out", + type: "Asset", + }, + { + name: "at", + type: "Hash", + isOptional: true, + }, + ], + type: "SerdeWrapper", }, - TokensAccountData: { - free: "Balance", - reserved: "Balance", - frozen: "Balance", + getSpotPrices: { + description: "Gets spot prices for a range of blocks", + params: [ + { + name: "pool_id", + type: "u128", + }, + { + name: "asset_in", + type: "Asset", + }, + { + name: "asset_out", + type: "Asset", + }, + { + name: "blocks", + type: "Vec", + }, + ], + type: "Vec", }, }, - }); + }, + typesAlias: { + tokens: { + AccountData: "TokensAccountData", + }, + }, + types: { + ...typesFromDefs(zeitgeistDefinitions), + BalanceInfo: { + amount: "Balance", + }, + TokensAccountData: { + free: "Balance", + reserved: "Balance", + frozen: "Balance", + }, + }, +}); + +export const lazyInitApi = ( + endpoint?: string +): [WsProvider, () => Promise] => { + const provider = new WsProvider(endpoint, 1200, undefined, 15000); + return [provider, () => ApiPromise.create(constructApiOptions(provider))]; +}; + +export const initApi = ( + endpoint = "wss://bsr.zeitgeist.pm" +): Promise => { + return ApiPromise.create(constructApiOptions(new WsProvider(endpoint))); }; export const unsubOrWarns = (unsub: () => void) => {