Skip to content

Commit

Permalink
ALL-1234: disable evicting nodes option
Browse files Browse the repository at this point in the history
  • Loading branch information
Filip KaΕ‘tovskΓ½ committed Dec 20, 2024
1 parent ad37b59 commit 874e4ae
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/connector/tatum.connector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export class TatumConnector {
}
const response = await res.json()
if (response?.error) {
return await this.retry(url, request, responseBody, retry)
return response
}
return response
}
Expand Down
31 changes: 26 additions & 5 deletions src/service/rpc/generic/LoadBalancer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,16 @@ export class LoadBalancer implements AbstractRpcInterface {
}
private interval: ReturnType<typeof setInterval>
private network: Network
private evictNodesOnFailure: boolean
private noActiveNode = false

constructor(private readonly id: string) {
this.connector = Container.of(this.id).get(TatumConnector)
this.network = Container.of(this.id).get(CONFIG).network

const config = Container.of(this.id).get(CONFIG)
this.network = config.network
this.evictNodesOnFailure = !!config.rpc?.evictNodesOnFailure

this.logger = Container.of(this.id).get(LOGGER)
}

Expand Down Expand Up @@ -147,6 +152,12 @@ export class LoadBalancer implements AbstractRpcInterface {
}
}

private resetFailedStatuses(nodeType: RpcNodeType) {
for (const server of this.rpcUrls[nodeType]) {
server.failed = false
}
}

private async checkStatuses() {
try {
await this.checkStatus(RpcNodeType.NORMAL)
Expand Down Expand Up @@ -496,20 +507,30 @@ export class LoadBalancer implements AbstractRpcInterface {
throw e
}

const servers = this.rpcUrls[nodeType] as RpcStatus[]

/**
* If the node is not responding, it will be marked as failed.
* New node will be selected and will be used for the given blockchain.
*/
const servers = this.rpcUrls[nodeType] as RpcStatus[]

servers[activeIndex].failed = true

const { index, fastestServer } = LoadBalancer.getFastestServer(
servers,
rpcConfig?.allowedBlocksBehind as number,
)

if (index === -1) {
this.logger.error(
`Looks like your request is malformed or all RPC nodes are down. Turn on verbose mode to see more details and check status pages.`,
)
if (this.evictNodesOnFailure) {
this.logger.error(
`Looks like your request is malformed or all RPC nodes are down. Turn on verbose mode to see more details and check status pages.`,
)
} else {
// Recover failed nodes, prepare them for the next round of requests
this.resetFailedStatuses(nodeType)
}

throw e
}
Utils.log({
Expand Down
9 changes: 8 additions & 1 deletion src/service/tatum/tatum.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,16 @@ export interface TatumConfig {
nodes?: RpcNode[]

/**
* If this is set to `true`, the SDK will not automatically load balance and failover between the available OpenRPC nodes and will use the fastest URL fetched during the startup. Defaults to `false`.
* If this is set to `true`, the SDK will not automatically load balance and failover between the available OpenRPC nodes and will use the fastest URL fetched during the startup. Defaults to `false` unless there only a single node is provided.
*/
oneTimeLoadBalancing?: boolean

/**
* If this is set to `true`, the SDK will evict nodes from routing pool if they are failing. If `oneTimeLoadBalancing` is set to `true` or you haven't provided your own rpc nodes, this parameter will default to `false`. Defaults to `true` otherwise.
*
* We discourage setting this to `true` if you are using `oneTimeLoadBalancing` as it will result in the SDK not being able to recover a failing node.
*/
evictNodesOnFailure?: boolean
}

/**
Expand Down
22 changes: 20 additions & 2 deletions src/service/tatum/tatum.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Container, Service } from 'typedi'
import { isLoadBalancerNetwork, Network } from '../../dto'
import { Network, isLoadBalancerNetwork } from '../../dto'
import { CONFIG, Constant, EnvUtils, LOGGER, LoggerUtils, Utils } from '../../util'
import {
ExtensionConstructor,
Expand Down Expand Up @@ -84,6 +84,10 @@ export class TatumSDK {

const mergedConfig = Utils.deepMerge(defaultConfig, config) as TatumConfig

if (mergedConfig.rpc && this.shouldEvictNodesOnFailure(mergedConfig)) {
mergedConfig.rpc.evictNodesOnFailure = true
}

LoggerUtils.setLoggerForEnv(mergedConfig, EnvUtils.isDevelopment(), EnvUtils.isBrowser())

// TODO: check when rpc is customized if there is allowedBlocksBehind if not throw error or set default
Expand All @@ -103,7 +107,9 @@ export class TatumSDK {
}

if (isLoadBalancerNetwork(mergedConfig.network)) {
const loadBalancer = Container.of(id).get(mergedConfig.network === Network.TRON ? TronLoadBalancer : LoadBalancer)
const loadBalancer = Container.of(id).get(
mergedConfig.network === Network.TRON ? TronLoadBalancer : LoadBalancer,
)
await loadBalancer.init()
}

Expand Down Expand Up @@ -185,4 +191,16 @@ export class TatumSDK {
}
return result
}

private static shouldEvictNodesOnFailure(config: TatumConfig): boolean | undefined {
if (config.rpc?.evictNodesOnFailure !== undefined && config.rpc?.oneTimeLoadBalancing !== null) {
return config.rpc.evictNodesOnFailure
}

if (!config.rpc?.nodes) {
return false
}

return !config.rpc?.oneTimeLoadBalancing
}
}

0 comments on commit 874e4ae

Please sign in to comment.