Last active
March 18, 2023 13:59
-
-
Save junkor-1011/71fd265383028051e03afd2a533f78bf to your computer and use it in GitHub Desktop.
retry-function(TypeScript)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Show hidden characters
{ | |
"compilerOptions": { | |
"allowJs": false, | |
"jsx": "react", | |
"lib": ["deno.window"], | |
"strict": true | |
}, | |
"lint": { | |
"files": { | |
// "include": ["src"], | |
"include": ["."], | |
"exclude": ["public"] | |
}, | |
"rules": { | |
"tags": ["recommended"], | |
"exclude": [] | |
} | |
}, | |
"fmt": { | |
"files": { | |
// "include": ["src/"], | |
"include": ["./"], | |
"exclude": [".vscode", ".env"] | |
}, | |
"options": { | |
"useTabs": false, | |
"lineWidth": 100, | |
"indentWidth": 2, | |
"singleQuote": true, | |
"proseWrap": "preserve" | |
} | |
}, | |
// "importMap": "import_map.json", | |
"tasks": { | |
"test": "deno test" | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { retry } from './retry.ts'; | |
// deno-lint-ignore require-await | |
const throwError = async (): Promise<string> => { | |
throw new Error('test error'); | |
// deno-lint-ignore no-unreachable | |
return 'success'; | |
}; | |
// no wait | |
console.log('test: retryCounts'); | |
console.time(); | |
const resultA = await retry( | |
throwError, | |
{ | |
retryCounts: 5, | |
}, | |
); | |
console.timeEnd(); | |
if (resultA.errors.length !== 5) throw new Error('unknown error'); | |
console.log('resultA', resultA); | |
console.log(` | |
================================================= | |
`); | |
// wait time | |
console.log('test: retry wait time'); | |
console.time(); | |
const resultB = await retry( | |
throwError, | |
{ | |
retryCounts: 3, | |
retryWaitMsec: 500, | |
}, | |
); | |
console.timeEnd(); | |
if (resultB.errors.length !== 3) throw new Error('unknown error'); | |
console.log('resultB', resultB); | |
console.log(` | |
================================================= | |
`); | |
// success with retry | |
console.log('test: success with retry & reporter'); | |
const genSuccessWithRetry = (n: number): () => Promise<string> => { | |
let count = 0; | |
const fetchIp = async (): Promise<string> => { | |
if (count < n) { | |
count++; | |
throw new Error('failed to fetch ip'); | |
} | |
const ip = await fetch('https://checkip.amazonaws.com/').then((res) => res.text()); | |
return ip; | |
}; | |
return fetchIp; | |
}; | |
const fetchIp3 = genSuccessWithRetry(3); | |
console.time(); | |
const resultC = await retry( | |
fetchIp3, | |
{ | |
retryCounts: 10, | |
retryWaitMsec: 700, | |
errorReporter: console.warn, | |
}, | |
); | |
console.timeEnd(); | |
if (resultC.errors.length !== 3) throw new Error('implement error'); | |
console.log('resultC', resultC); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { retry } from './retry.ts'; | |
const excution = () => fetch('https://checkip.amazonaws.com/').then((response) => response.text()); | |
console.time(); | |
const result = await retry( | |
excution, | |
{ | |
retryCounts: 3, | |
retryWaitMsec: 3000, | |
errorReporter: console.error, | |
}, | |
); | |
console.timeEnd(); | |
if (!result.success) throw new Error('failed'); | |
const { data, errors } = result; | |
console.log(data, errors); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export type TRetryResult<T> = { | |
success: true; | |
data: T; | |
errors: unknown[]; | |
} | { | |
success: false; | |
data: null; | |
errors: unknown[]; | |
}; | |
export type TRetryOptions = { | |
retryCounts: number; | |
retryWaitMsec?: number; | |
errorReporter?: <T extends unknown[]>(...massages: readonly [...T]) => void; | |
}; | |
export const retry = async <T>( | |
execution: () => Promise<T>, | |
opts: TRetryOptions, | |
): Promise<TRetryResult<T>> => { | |
const errors: unknown[] = []; | |
while (errors.length < opts.retryCounts) { | |
try { | |
const data = await execution(); | |
return { | |
success: true, | |
data, | |
errors, | |
}; | |
} catch (error) { | |
if (opts.errorReporter != null) { | |
opts.errorReporter(error); | |
} | |
errors.push(error); | |
} | |
await new Promise((resolve) => setTimeout(resolve, opts.retryWaitMsec ?? 0)); | |
} | |
return { | |
success: false, | |
data: null, | |
errors, | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment