10
10
Simple Async busy wait module for Node.JS
11
11
12
12
## Main features
13
- - Simple api to busy wait for a desired outcome
14
- - Slim library (65 lines of code, no dependencies)
13
+ - Simple api to busy wait for a desired outcome
14
+ - Exponential backoff (with optional full jitter) support
15
+ - Slim library (single file, 100 lines of code, no dependencies)
15
16
- Full typescript support
16
17
17
18
## Quick example
18
19
``` typescript
19
20
import { busywait } from ' busywait' ;
20
- import {IBusyWaitResult } from ' busywait' ;
21
21
22
22
const waitUntil = Date .now () + 2500 ;
23
- const checkFn = (iteration : number ): Promise <string > => {
24
- return new Promise ((resolve , reject ) => {
25
- console .log (' running iteration' , iteration );
26
- if (Date .now () > waitUntil ) {
27
- return resolve (' success' );
28
- } else {
29
- return reject ();
30
- }
31
- });
23
+
24
+ const checkFn = async (iteration : number , delay : number ): Promise <string > => {
25
+ console .log (` Running iteration ${iteration } after delay of ${delay }ms ` );
26
+ if (Date .now () > waitUntil ) {
27
+ return ` success ` ;
28
+ }
29
+ throw new Error (' custom error' );
30
+ };
31
+
32
+ (async () => {
33
+ const result = await busywait (checkFn , {
34
+ sleepTime: 500 ,
35
+ maxChecks: 20 ,
36
+ })
37
+ console .log (` Finished after ${result .backoff .time }ms (${result .backoff .iterations } iterations) with result ${result .result } ` );
38
+ })();
39
+ ```
40
+
41
+ Will result in:
42
+ ``` bash
43
+ Running iteration 1 after delay of 0ms
44
+ Running iteration 2 after delay of 500ms
45
+ Running iteration 3 after delay of 500ms
46
+ Running iteration 4 after delay of 500ms
47
+ Running iteration 5 after delay of 500ms
48
+ Running iteration 6 after delay of 500ms
49
+ Finished after 2511ms (6 iterations) with result success
50
+ ```
51
+
52
+ ### Exponential backoff
53
+
54
+ ``` typescript
55
+ import { busywait } from ' busywait' ;
56
+
57
+ const waitUntil = Date .now () + 2500 ;
58
+
59
+ const checkFn = async (iteration : number , delay : number ): Promise <string > => {
60
+ console .log (` Running iteration ${iteration } after delay of ${delay }ms ` );
61
+ if (Date .now () > waitUntil ) {
62
+ return ` success ` ;
63
+ }
64
+ throw new Error (' custom error' );
32
65
};
33
- busywait (checkFn , {
34
- sleepTime: 500 ,
35
- maxChecks: 20 ,
36
- })
37
- .then ((result : IBusyWaitResult <string >) => {
38
- console .log (' finished after' , result .iterations , ' iterations' , ' with' +
39
- ' result' , result .result );
40
- });
66
+
67
+ (async () => {
68
+ const result = await busywait (checkFn , {
69
+ sleepTime: 100 ,
70
+ jitter: ' none' ,
71
+ multiplier: 2 ,
72
+ })
73
+ console .log (` Finished after ${result .backoff .time }ms (${result .backoff .iterations } iterations) with result ${result .result } ` );
74
+ })();
41
75
```
76
+
77
+ Will result in:
78
+ ``` bash
79
+ Running iteration 1 after delay of 0ms
80
+ Running iteration 2 after delay of 100ms
81
+ Running iteration 3 after delay of 200ms
82
+ Running iteration 4 after delay of 400ms
83
+ Running iteration 5 after delay of 800ms
84
+ Running iteration 6 after delay of 1600ms
85
+ Finished after 3111ms (6 iterations) with result success
86
+ ```
87
+
88
+ ### Exponential backoff with full jitter
89
+
90
+ ``` typescript
91
+ import { busywait } from ' busywait' ;
92
+
93
+ const waitUntil = Date .now () + 2500 ;
94
+
95
+ const checkFn = async (iteration : number , delay : number ): Promise <string > => {
96
+ console .log (` Running iteration ${iteration } after delay of ${delay }ms ` );
97
+ if (Date .now () > waitUntil ) {
98
+ return ` success ` ;
99
+ }
100
+ throw new Error (' custom error' );
101
+ };
102
+
103
+ (async () => {
104
+ const result = await busywait (checkFn , {
105
+ sleepTime: 100 ,
106
+ jitter: ' full' ,
107
+ multiplier: 2 ,
108
+ waitFirst: true ,
109
+ })
110
+ console .log (` Finished after ${result .backoff .time }ms (${result .backoff .iterations } iterations) with result ${result .result } ` );
111
+ })();
112
+ ```
113
+
42
114
Will result in:
43
115
``` bash
44
- running iteration 1
45
- running iteration 2
46
- running iteration 3
47
- running iteration 4
48
- running iteration 5
49
- running iteration 6
50
- finished after 6 iterations with result success
116
+ Running iteration 1 after delay of 78ms
117
+ Running iteration 2 after delay of 154ms
118
+ Running iteration 3 after delay of 228ms
119
+ Running iteration 4 after delay of 605ms
120
+ Running iteration 5 after delay of 136ms
121
+ Running iteration 6 after delay of 1652ms
122
+ Finished after 2863ms ( 6 iterations) with result success
51
123
```
52
124
53
125
## Install
@@ -62,28 +134,32 @@ npm install busywait
62
134
A function that takes a single optional argument, which is the current iteration number.
63
135
The function can either:
64
136
- return a non promised value (in which case, a failed check should throw an error)
65
- - return promised value (in which case, a failed check should return a rejection )
137
+ - return promised value (in which case, a failed check should return a rejected promise )
66
138
67
139
#### options
68
140
69
141
##### mandatory
70
142
71
- - ` sleepTime ` - Time in ms to wait between checks
72
- - ` maxChecks ` - The max number of checks to perform before failing
143
+ - ` sleepTime ` - Time in ms to wait between checks. In the exponential mode, will be the base sleep time.
73
144
74
145
##### optional
75
146
147
+ - ` multiplier ` - The exponential multiplier. Set to 2 or higher to achieve exponential backoff (default: 1 - i.e. linear backoff)
148
+ - ` maxDelay ` - The max delay value between checks in ms (default: infinity)
149
+ - ` maxChecks ` - The max number of checks to perform before failing (default: infinity)
76
150
- ` waitFirst ` - Should we wait the ` sleepTime ` before performing the first check (default: false)
151
+ - ` jitter ` - ('none' | 'full') The [ jitter] ( https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/ ) mode to use (default: none)
77
152
- ` failMsg ` - Custom error message to reject the promise with
78
153
79
154
### Return value
80
155
81
156
Return value is a promise.
82
- - The promise will be resolved if the ` checkFn ` returned a valid value ( resolved promise or did not throw an error) within a legal number of checks.
83
- - The promise will be rejected if the ` checkFn ` rejected ( or threw an error) ` maxChecks ` times.
157
+ - The promise will be resolved if the ` checkFn ` was resolved within a legal number of checks.
158
+ - The promise will be rejected if the ` checkFn ` rejected (or threw an error) ` maxChecks ` times.
84
159
85
160
Promise resolved value:
86
- - ` iterations ` - The number of iterations it took to finish
161
+ - ` backoff.iterations ` - The number of iterations it took to finish
162
+ - ` backoff.time ` - The number of time it took to finish
87
163
- ` result ` - The resolved value of ` checkFn `
88
164
89
165
## Contributing
0 commit comments