Skip to content

Commit

Permalink
Merge pull request #165 from algorandfoundation/indexer-retry
Browse files Browse the repository at this point in the history
fix: Resolving problem where indexer requests weren't retrying
  • Loading branch information
robdmoore authored Nov 17, 2023
2 parents 54521df + 39bb489 commit 55b865b
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ ___

#### Defined in

[src/types/algo-http-client-with-retry.ts:67](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algo-http-client-with-retry.ts#L67)
[src/types/algo-http-client-with-retry.ts:71](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algo-http-client-with-retry.ts#L71)

___

Expand All @@ -170,7 +170,7 @@ ___

#### Defined in

[src/types/algo-http-client-with-retry.ts:54](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algo-http-client-with-retry.ts#L54)
[src/types/algo-http-client-with-retry.ts:58](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algo-http-client-with-retry.ts#L58)

___

Expand All @@ -197,4 +197,4 @@ ___

#### Defined in

[src/types/algo-http-client-with-retry.ts:58](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algo-http-client-with-retry.ts#L58)
[src/types/algo-http-client-with-retry.ts:62](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/algo-http-client-with-retry.ts#L62)
48 changes: 48 additions & 0 deletions src/network-client.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,54 @@ import * as algokit from './'
describe('network-clients', () => {
envResetFixture()

// Don't spam algonode all the time, remove the `skip` to run these manually
describe.skip('Retry', () => {
/*
*https://nodely.io/api/*
The API requests are rate limited per source IP address with request shaping.
A burst of 90 rps is allowed and all responses are delayed artificially to make sure that (if called sequentially) they will not exceed the quota.
Queries exceeding the 90rps in burst or sustained 60rps will get HTTP 429 error.
*/
// Create a mock logger to track the number of retries
const myLogger = {
error: jest.fn(),
warn: jest.fn(),
info: jest.fn(),
debug: jest.fn(),
verbose: jest.fn(),
}
algokit.Config.configure({ logger: myLogger })
afterEach(() => {
jest.clearAllMocks()
})
test('Retries indexer calls', async () => {
const indexer = await algokit.getAlgoIndexerClient(algokit.getAlgoNodeConfig('testnet', 'indexer'))

const response = await Promise.all(
new Array(150).fill(0).map(async (_) => {
return await indexer.lookupAccountByID('XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA').do()
}),
)
expect(response.length).toBe(150)
expect(myLogger.warn).toHaveBeenCalledWith(
'algosdk request failed 1 times. Retrying in 0ms: URLTokenBaseHTTPError: Network request error. Received status 429 (Too Many Requests)',
)
}, 10_000)
test('Retries algod calls', async () => {
const algod = await algokit.getAlgoClient(algokit.getAlgoNodeConfig('testnet', 'algod'))

const response = await Promise.all(
new Array(150).fill(0).map(async (_) => {
return await algod.accountInformation('XBYLS2E6YI6XXL5BWCAMOA4GTWHXWENZMX5UHXMRNWWUQ7BXCY5WC5TEPA').do()
}),
)
expect(response.length).toBe(150)
expect(myLogger.warn).toHaveBeenCalledWith(
'algosdk request failed 1 times. Retrying in 0ms: URLTokenBaseHTTPError: Network request error. Received status 429 (Too Many Requests)',
)
}, 10_000)
})

describe('Config', () => {
test('Gets algod config from environment', () => {
process.env.ALGOD_SERVER = 'http://localhost'
Expand Down
6 changes: 5 additions & 1 deletion src/types/algo-http-client-with-retry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ export class AlgoHttpClientWithRetry extends URLTokenBaseHTTPClient {
}
// Only retry for one of the hardcoded conditions
if (
!(AlgoHttpClientWithRetry.RETRY_ERROR_CODES.includes(err.code) || AlgoHttpClientWithRetry.RETRY_STATUS_CODES.includes(err.status))
!(
AlgoHttpClientWithRetry.RETRY_ERROR_CODES.includes(err.code) ||
AlgoHttpClientWithRetry.RETRY_STATUS_CODES.includes(Number(err.status)) ||
('response' in err && AlgoHttpClientWithRetry.RETRY_STATUS_CODES.includes(Number(err.response.status)))
)
) {
throw err
}
Expand Down

0 comments on commit 55b865b

Please sign in to comment.