diff --git a/src/generate/contractsGenerator.ts b/src/generate/contractsGenerator.ts index d3a80e0..f116a47 100644 --- a/src/generate/contractsGenerator.ts +++ b/src/generate/contractsGenerator.ts @@ -18,6 +18,7 @@ import { isClarityAbiTuple, } from "./contractAbi"; import { assertNever, mapValues } from "../utils/helpers"; +import { asyncAutoRetry } from "../utils/asyncAutoRetry"; import axios from "axios"; type TranscoderDefArgument = TranscoderDef | Record; @@ -32,7 +33,7 @@ const toTranscoderDef = ({ }): { def: TranscoderDef } => { if (isClarityAbiPrimitive(type)) { if (type === "uint128") { - return {def: ["uintT"]}; + return { def: ["uintT"] }; } else if (type === "int128") { return { def: ["intT"] }; } else if (type === "bool") { @@ -258,10 +259,12 @@ export const generateContractFromAbi = async ({ apiHost: string; output: string; packageName: string; - contractOverwrites: {[from: string]: string} + contractOverwrites: { [from: string]: string }; }): Promise => { - const url = `${apiHost}/v2/contracts/interface/${principal}/${contractOverwrites[contractName] ?? contractName}`; - const response = await axios.get(url); + const url = `${apiHost}/v2/contracts/interface/${principal}/${ + contractOverwrites[contractName] ?? contractName + }`; + const response = await asyncAutoRetry(() => axios.get(url)); const interfaceData: ClarityAbi = response.data; const defs = {} as Record; for (const func of interfaceData.functions) { diff --git a/src/generate/index.ts b/src/generate/index.ts index b46fc0e..94a8cb5 100644 --- a/src/generate/index.ts +++ b/src/generate/index.ts @@ -11,9 +11,11 @@ export async function generateContracts( output: string, name: string, packageName: string = "clarity-codegen", - contractOverwrites: {[from: string]: string} = {} + contractOverwrites: {[from: string]: string} = {}, + options: {concurrency?: number} = {} ) { - const batch = new YBatch({ concurrency: 16 }); + const concurrency = options.concurrency?? 16 + const batch = new YBatch({ concurrency }); for (const cname of contracts) { await batch.add(async () => { console.log(`Generating contract ${typeof principal === 'string' ? principal : principal(cname)}.${cname}`); diff --git a/src/utils/asyncAutoRetry.ts b/src/utils/asyncAutoRetry.ts new file mode 100644 index 0000000..91463e9 --- /dev/null +++ b/src/utils/asyncAutoRetry.ts @@ -0,0 +1,26 @@ +export async function asyncAutoRetry( + action: () => Promise, + options: { + count?: number; + isNeedRetry?: (error: any) => boolean; + } = {} +): Promise { + const count = options.count ?? 20; + const isNeedRetry = options.isNeedRetry ?? (() => true); + + let remainingRetryCount = count; + while (true) { + try { + return await action(); + } catch (error) { + remainingRetryCount -= 1; + + if (remainingRetryCount >= 0 && isNeedRetry(error)) { + await new Promise((resolve) => setTimeout(resolve, 1000)); + continue; + } + + throw error; + } + } +}