@@ -10,163 +10,52 @@ function apiError(headers?: Record<string, string>): MessageV2.APIError {
1010 } ) . toObject ( ) as MessageV2 . APIError
1111}
1212
13- describe ( "session.retry.getRetryDelayInMs " , ( ) => {
14- test ( "doubles delay on each attempt when headers missing" , ( ) => {
13+ describe ( "session.retry.delay " , ( ) => {
14+ test ( "caps delay at 30 seconds when headers missing" , ( ) => {
1515 const error = apiError ( )
16- const delays = Array . from ( { length : 10 } , ( _ , index ) => SessionRetry . getRetryDelayInMs ( error , index + 1 ) )
17- expect ( delays ) . toStrictEqual ( [ 2000 , 4000 , 8000 , 16000 , 32000 , 64000 , 128000 , 256000 , 512000 , undefined ] )
16+ const delays = Array . from ( { length : 10 } , ( _ , index ) => SessionRetry . delay ( error , index + 1 ) )
17+ expect ( delays ) . toStrictEqual ( [ 2000 , 4000 , 8000 , 16000 , 30000 , 30000 , 30000 , 30000 , 30000 , 30000 ] )
1818 } )
1919
2020 test ( "prefers retry-after-ms when shorter than exponential" , ( ) => {
2121 const error = apiError ( { "retry-after-ms" : "1500" } )
22- expect ( SessionRetry . getRetryDelayInMs ( error , 4 ) ) . toBe ( 1500 )
22+ expect ( SessionRetry . delay ( error , 4 ) ) . toBe ( 1500 )
2323 } )
2424
2525 test ( "uses retry-after seconds when reasonable" , ( ) => {
2626 const error = apiError ( { "retry-after" : "30" } )
27- expect ( SessionRetry . getRetryDelayInMs ( error , 3 ) ) . toBe ( 30000 )
27+ expect ( SessionRetry . delay ( error , 3 ) ) . toBe ( 30000 )
2828 } )
2929
3030 test ( "accepts http-date retry-after values" , ( ) => {
3131 const date = new Date ( Date . now ( ) + 20000 ) . toUTCString ( )
3232 const error = apiError ( { "retry-after" : date } )
33- const delay = SessionRetry . getRetryDelayInMs ( error , 1 )
34- expect ( delay ) . toBeGreaterThanOrEqual ( 19000 )
35- expect ( delay ) . toBeLessThanOrEqual ( 20000 )
33+ const d = SessionRetry . delay ( error , 1 )
34+ expect ( d ) . toBeGreaterThanOrEqual ( 19000 )
35+ expect ( d ) . toBeLessThanOrEqual ( 20000 )
3636 } )
3737
3838 test ( "ignores invalid retry hints" , ( ) => {
3939 const error = apiError ( { "retry-after" : "not-a-number" } )
40- expect ( SessionRetry . getRetryDelayInMs ( error , 1 ) ) . toBe ( 2000 )
40+ expect ( SessionRetry . delay ( error , 1 ) ) . toBe ( 2000 )
4141 } )
4242
4343 test ( "ignores malformed date retry hints" , ( ) => {
4444 const error = apiError ( { "retry-after" : "Invalid Date String" } )
45- expect ( SessionRetry . getRetryDelayInMs ( error , 1 ) ) . toBe ( 2000 )
45+ expect ( SessionRetry . delay ( error , 1 ) ) . toBe ( 2000 )
4646 } )
4747
4848 test ( "ignores past date retry hints" , ( ) => {
4949 const pastDate = new Date ( Date . now ( ) - 5000 ) . toUTCString ( )
5050 const error = apiError ( { "retry-after" : pastDate } )
51- expect ( SessionRetry . getRetryDelayInMs ( error , 1 ) ) . toBe ( 2000 )
51+ expect ( SessionRetry . delay ( error , 1 ) ) . toBe ( 2000 )
5252 } )
5353
54- test ( "returns undefined when delay exceeds 10 minutes" , ( ) => {
55- const error = apiError ( )
56- expect ( SessionRetry . getRetryDelayInMs ( error , 10 ) ) . toBeUndefined ( )
57- } )
58-
59- test ( "returns undefined when retry-after exceeds 10 minutes" , ( ) => {
54+ test ( "returns undefined when retry-after exceeds 10 minutes with headers" , ( ) => {
6055 const error = apiError ( { "retry-after" : "50" } )
61- expect ( SessionRetry . getRetryDelayInMs ( error , 1 ) ) . toBe ( 50000 )
56+ expect ( SessionRetry . delay ( error , 1 ) ) . toBe ( 50000 )
6257
6358 const longError = apiError ( { "retry-after-ms" : "700000" } )
64- expect ( SessionRetry . getRetryDelayInMs ( longError , 1 ) ) . toBeUndefined ( )
65- } )
66- } )
67-
68- describe ( "session.retry.getBoundedDelay" , ( ) => {
69- test ( "returns full delay when under time budget" , ( ) => {
70- const error = apiError ( )
71- const startTime = Date . now ( )
72- const delay = SessionRetry . getBoundedDelay ( {
73- error,
74- attempt : 1 ,
75- startTime,
76- } )
77- expect ( delay ) . toBe ( 2000 )
78- } )
79-
80- test ( "returns remaining time when delay exceeds budget" , ( ) => {
81- const error = apiError ( )
82- const startTime = Date . now ( ) - 598_000 // 598 seconds elapsed, 2 seconds remaining
83- const delay = SessionRetry . getBoundedDelay ( {
84- error,
85- attempt : 1 ,
86- startTime,
87- } )
88- expect ( delay ) . toBeGreaterThanOrEqual ( 1900 )
89- expect ( delay ) . toBeLessThanOrEqual ( 2100 )
90- } )
91-
92- test ( "returns undefined when time budget exhausted" , ( ) => {
93- const error = apiError ( )
94- const startTime = Date . now ( ) - 600_000 // exactly 10 minutes elapsed
95- const delay = SessionRetry . getBoundedDelay ( {
96- error,
97- attempt : 1 ,
98- startTime,
99- } )
100- expect ( delay ) . toBeUndefined ( )
101- } )
102-
103- test ( "returns undefined when time budget exceeded" , ( ) => {
104- const error = apiError ( )
105- const startTime = Date . now ( ) - 700_000 // 11+ minutes elapsed
106- const delay = SessionRetry . getBoundedDelay ( {
107- error,
108- attempt : 1 ,
109- startTime,
110- } )
111- expect ( delay ) . toBeUndefined ( )
112- } )
113-
114- test ( "respects custom maxDuration" , ( ) => {
115- const error = apiError ( )
116- const startTime = Date . now ( ) - 58_000 // 58 seconds elapsed
117- const delay = SessionRetry . getBoundedDelay ( {
118- error,
119- attempt : 1 ,
120- startTime,
121- maxDuration : 60_000 , // 1 minute max
122- } )
123- expect ( delay ) . toBeGreaterThanOrEqual ( 1900 )
124- expect ( delay ) . toBeLessThanOrEqual ( 2100 )
125- } )
126-
127- test ( "caps exponential backoff to remaining time" , ( ) => {
128- const error = apiError ( )
129- const startTime = Date . now ( ) - 595_000 // 595 seconds elapsed, 5 seconds remaining
130- const delay = SessionRetry . getBoundedDelay ( {
131- error,
132- attempt : 5 , // would normally be 32 seconds
133- startTime,
134- } )
135- expect ( delay ) . toBeGreaterThanOrEqual ( 4900 )
136- expect ( delay ) . toBeLessThanOrEqual ( 5100 )
137- } )
138-
139- test ( "respects server retry-after within budget" , ( ) => {
140- const error = apiError ( { "retry-after" : "30" } )
141- const startTime = Date . now ( ) - 550_000 // 550 seconds elapsed, 50 seconds remaining
142- const delay = SessionRetry . getBoundedDelay ( {
143- error,
144- attempt : 1 ,
145- startTime,
146- } )
147- expect ( delay ) . toBe ( 30000 )
148- } )
149-
150- test ( "caps server retry-after to remaining time" , ( ) => {
151- const error = apiError ( { "retry-after" : "30" } )
152- const startTime = Date . now ( ) - 590_000 // 590 seconds elapsed, 10 seconds remaining
153- const delay = SessionRetry . getBoundedDelay ( {
154- error,
155- attempt : 1 ,
156- startTime,
157- } )
158- expect ( delay ) . toBeGreaterThanOrEqual ( 9900 )
159- expect ( delay ) . toBeLessThanOrEqual ( 10100 )
160- } )
161-
162- test ( "returns undefined when getRetryDelayInMs returns undefined" , ( ) => {
163- const error = apiError ( )
164- const startTime = Date . now ( )
165- const delay = SessionRetry . getBoundedDelay ( {
166- error,
167- attempt : 10 , // exceeds RETRY_MAX_DELAY
168- startTime,
169- } )
170- expect ( delay ) . toBeUndefined ( )
59+ expect ( SessionRetry . delay ( longError , 1 ) ) . toBeUndefined ( )
17160 } )
17261} )
0 commit comments