refactor(retry): remove dead helpers from retry-utils (withRetry, retryable, RetryManager)
Audit follow-up. After verifying the codebase, three exports of retry-utils.ts have ZERO production callers: - `withRetry` decorator (lines 419-440): unused - `retryable` wrapper (lines 442-453): unused (1 self-test only) - `RetryManager` class (lines 455-549): unused (1 self-test only) Note: `MessageRetryManager` in messages-send.ts is a separate class, not the same thing. The kept exports are still used: - `retry()` function: used by decode-wa-message.ts for Bad MAC recovery - `RetryExhaustedError`, `RetryOptions`, `RetryContext`: used same place - `RETRY_BACKOFF_DELAYS`, `RETRY_JITTER_FACTOR`: re-exported via Defaults - `retryPredicates`, `retryConfigs`: helper presets (kept; small) Removed `EventEmitter` import (was only used by the deleted RetryManager). Removed `retryable` and `RetryManager` from test imports + their describe blocks (5 tests removed, all targeting the deleted code). Net: -148 lines from retry-utils.ts, -90 lines from its test file. 803 tests pass (was 809; 6 deleted tests covered the removed code). Now the InfiniteAPI retry surface is: - `retry-utils.ts:retry()` for Bad MAC recovery (decryption layer) - `bounded-retry.ts:withBoundedRetry()` for socket operation retry (uploadPreKeys), with WhatsApp Android empirical defaults No redundancy: each helper handles a distinct concern.
This commit is contained in:
@@ -11,12 +11,10 @@ import {
|
||||
retry,
|
||||
RETRY_BACKOFF_DELAYS,
|
||||
RETRY_JITTER_FACTOR,
|
||||
retryable,
|
||||
RetryAbortedError,
|
||||
retryConfigs,
|
||||
type RetryContext,
|
||||
RetryExhaustedError,
|
||||
RetryManager,
|
||||
retryPredicates,
|
||||
retryWithResult
|
||||
} from '../../Utils/retry-utils.js'
|
||||
@@ -315,103 +313,6 @@ describe('createRetrier', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('retryable', () => {
|
||||
it('should wrap function with retry', async () => {
|
||||
let attempts = 0
|
||||
|
||||
const fn = retryable(
|
||||
() => {
|
||||
attempts++
|
||||
if (attempts < 2) throw new Error('Failing')
|
||||
return 'wrapped result'
|
||||
},
|
||||
{
|
||||
maxAttempts: 5,
|
||||
baseDelay: 10,
|
||||
collectMetrics: false
|
||||
}
|
||||
)
|
||||
|
||||
const result = await fn()
|
||||
|
||||
expect(result).toBe('wrapped result')
|
||||
expect(attempts).toBe(2)
|
||||
})
|
||||
})
|
||||
|
||||
describe('RetryManager', () => {
|
||||
let manager: RetryManager
|
||||
|
||||
beforeEach(() => {
|
||||
manager = new RetryManager({ baseDelay: 200, collectMetrics: false })
|
||||
})
|
||||
|
||||
it('should execute operation with id', async () => {
|
||||
const result = await manager.execute('op1', () => 'result')
|
||||
expect(result).toBe('result')
|
||||
})
|
||||
|
||||
it('should cancel active retry', async () => {
|
||||
let attempt = 0
|
||||
|
||||
const promise = manager.execute('cancelable', async () => {
|
||||
attempt++
|
||||
if (attempt === 1) {
|
||||
throw new Error('Temporary failure')
|
||||
}
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 1000))
|
||||
return 'result'
|
||||
})
|
||||
|
||||
// Cancel during retry delay
|
||||
setTimeout(() => manager.cancel('cancelable'), 100)
|
||||
|
||||
await expect(promise).rejects.toThrow()
|
||||
})
|
||||
|
||||
it('should check if operation is active', async () => {
|
||||
let resolve: () => void
|
||||
const promise = manager.execute(
|
||||
'active',
|
||||
() =>
|
||||
new Promise<string>(r => {
|
||||
resolve = () => r('done')
|
||||
})
|
||||
)
|
||||
|
||||
expect(manager.isActive('active')).toBe(true)
|
||||
|
||||
resolve!()
|
||||
await promise
|
||||
|
||||
expect(manager.isActive('active')).toBe(false)
|
||||
})
|
||||
|
||||
it('should cancel all operations', async () => {
|
||||
const promises = [
|
||||
manager.execute('op1', () => new Promise((_, reject) => setTimeout(() => reject(new Error()), 1000))),
|
||||
manager.execute('op2', () => new Promise((_, reject) => setTimeout(() => reject(new Error()), 1000)))
|
||||
]
|
||||
|
||||
setTimeout(() => manager.cancelAll(), 20)
|
||||
|
||||
await expect(Promise.all(promises)).rejects.toThrow()
|
||||
})
|
||||
|
||||
it('should emit events', async () => {
|
||||
const events: string[] = []
|
||||
|
||||
manager.on('attempt', () => events.push('attempt'))
|
||||
manager.on('success', () => events.push('success'))
|
||||
|
||||
await manager.execute('test', () => 'result')
|
||||
|
||||
expect(events).toContain('attempt')
|
||||
expect(events).toContain('success')
|
||||
})
|
||||
})
|
||||
|
||||
describe('retryPredicates', () => {
|
||||
describe('always', () => {
|
||||
it('should always return true', () => {
|
||||
|
||||
Reference in New Issue
Block a user