@@ -1639,7 +1639,7 @@ describe('ListWatchCache', () => {
16391639 deepStrictEqual ( delayValues , [ 1000 ] ) ;
16401640 } ) ;
16411641
1642- it ( 'should reconnect with backoff on TimeoutError' , async ( ) => {
1642+ it ( 'should reconnect on TimeoutError' , async ( ) => {
16431643 const fakeWatch = mock . mock ( Watch ) ;
16441644 const listObj = {
16451645 metadata : { resourceVersion : '12345' } as V1ListMeta ,
@@ -1682,6 +1682,63 @@ describe('ListWatchCache', () => {
16821682 strictEqual ( watchCalls , 2 ) ;
16831683 strictEqual ( errorEmitted , false ) ;
16841684 } ) ;
1685+
1686+ it ( 'should not back off between repeated TimeoutErrors' , async ( ) => {
1687+ const fakeWatch = mock . mock ( Watch ) ;
1688+ const listObj = {
1689+ metadata : { resourceVersion : '12345' } as V1ListMeta ,
1690+ items : [ ] as V1Namespace [ ] ,
1691+ } as V1NamespaceList ;
1692+
1693+ const listFn : ListPromise < V1Namespace > = ( ) => Promise . resolve ( listObj ) ;
1694+
1695+ let watchCalls = 0 ;
1696+ const delayValues : number [ ] = [ ] ;
1697+ const promise = new Promise ( ( resolve ) => {
1698+ mock . when (
1699+ fakeWatch . watch ( mock . anything ( ) , mock . anything ( ) , mock . anything ( ) , mock . anything ( ) ) ,
1700+ ) . thenCall ( ( ) => {
1701+ watchCalls ++ ;
1702+ resolve ( new AbortController ( ) ) ;
1703+ return Promise . resolve ( new AbortController ( ) ) ;
1704+ } ) ;
1705+ } ) ;
1706+
1707+ // ListWatch is constructed for its side effects (starts watching)
1708+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1709+ const cache = new ListWatch (
1710+ '/some/path' ,
1711+ mock . instance ( fakeWatch ) ,
1712+ listFn ,
1713+ true ,
1714+ undefined ,
1715+ undefined ,
1716+ {
1717+ delayFn : ( ms : number ) => {
1718+ delayValues . push ( ms ) ;
1719+ return Promise . resolve ( ) ;
1720+ } ,
1721+ } ,
1722+ ) ;
1723+ await promise ;
1724+ strictEqual ( watchCalls , 1 ) ;
1725+
1726+ const [ , , , doneHandler ] = mock . capture ( fakeWatch . watch ) . last ( ) ;
1727+
1728+ const timeoutError = ( ) =>
1729+ new DOMException ( 'The operation was aborted due to timeout' , 'TimeoutError' ) ;
1730+
1731+ await doneHandler ( timeoutError ( ) ) ;
1732+ await doneHandler ( timeoutError ( ) ) ;
1733+ await doneHandler ( timeoutError ( ) ) ;
1734+
1735+ strictEqual ( watchCalls , 4 ) ;
1736+ deepStrictEqual ( delayValues , [ ] ) ;
1737+
1738+ // Backoff is still applied to non-timeout reconnects.
1739+ await doneHandler ( null ) ;
1740+ deepStrictEqual ( delayValues , [ 1000 ] ) ;
1741+ } ) ;
16851742} ) ;
16861743
16871744describe ( 'delete items' , ( ) => {
0 commit comments