| 60 | description?: string) { |
| 61 | const signal = AsyncScope.abortSignal; |
| 62 | const innerFunction = async (messages: string[]) => { |
| 63 | let iterations = 0; |
| 64 | const logger = {log: messages.push.bind(messages)}; |
| 65 | while (true) { |
| 66 | signal?.throwIfAborted(); |
| 67 | const messagesBefore = messages.length; |
| 68 | const result = await fn(logger); |
| 69 | // On completing an iteration, remove any leftover messages from the previous iteration. |
| 70 | messages.splice(0, messagesBefore); |
| 71 | messages.push(`Iteration ${iterations++} result: ${result ? 'success' : `${result}`}`); |
| 72 | signal?.throwIfAborted(); |
| 73 | if (result) { |
| 74 | return result as Exclude<NonNullable<T>, false>; |
| 75 | } |
| 76 | await this.timeout(100); |
| 77 | } |
| 78 | }; |
| 79 | return await asyncScope.exec(innerFunction, description); |
| 80 | } |
| 81 | |