deno.land / std@0.173.0 / async / retry.ts

نووسراو ببینە
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
export class RetryError extends Error { constructor(cause: unknown, count: number) { super(`Exceeded max retry count (${count})`); this.name = "RetryError"; this.cause = cause; }}
export interface RetryOptions { /** How much to backoff after each retry. This is `2` by default. */ multiplier?: number; /** The maximum milliseconds between retries. This is `60000` by default. */ maxTimeout?: number; /** The maximum amount of retries until failure. This is `5` by default. */ maxAttempts?: number; /** The inital and minimum amount of milliseconds between retries. This is `1000` by default. */ minTimeout?: number;}
const defaultRetryOptions = { multiplier: 2, maxTimeout: 60000, maxAttempts: 5, minTimeout: 1000,};
/** * Creates a retry promise which resolves to the value of the input using exponential backoff. * If the input promise throws, it will be retried `maxAttempts` number of times. * It will retry the input every certain amount of milliseconds, starting at `minTimeout` and multiplying by the `multiplier` until it reaches the `maxTimeout` * * @example * ```typescript * import { retry } from "https://deno.land/std@$STD_VERSION/async/mod.ts"; * const req = async () => { * // some function that throws sometimes * }; * * // Below resolves to the first non-error result of `req` * const retryPromise = await retry(req, { * multiplier: 2, * maxTimeout: 60000, * maxAttempts: 5, * minTimeout: 100, * });``` */export async function retry<T>( fn: (() => Promise<T>) | (() => T), opts?: RetryOptions,) { const options: Required<RetryOptions> = { ...defaultRetryOptions, ...opts, };
if (options.maxTimeout >= 0 && options.minTimeout > options.maxTimeout) { throw new RangeError("minTimeout is greater than maxTimeout"); }
let timeout = options.minTimeout; let error: unknown;
for (let i = 0; i < options.maxAttempts; i++) { try { return await fn(); } catch (err) { await new Promise((r) => setTimeout(r, timeout)); timeout *= options.multiplier; timeout = Math.max(timeout, options.minTimeout); if (options.maxTimeout >= 0) { timeout = Math.min(timeout, options.maxTimeout); } error = err; } }
throw new RetryError(error, options.maxAttempts);}
std

Version Info

Tagged at
a year ago