Skip to content

Commit a761154

Browse files
authored
End runInLoop if it should be stopped (#117)
* End runInLoop if the it should be stopped * Add unit test for runInLoop stop signal
1 parent 1b06dc6 commit a761154

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

src/run-in-loop/index.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { createLogger } from '../logger';
2+
3+
import { runInLoop } from './index';
4+
5+
describe(runInLoop.name, () => {
6+
const logger = createLogger({
7+
colorize: true,
8+
enabled: true,
9+
minLevel: 'info',
10+
format: 'json',
11+
});
12+
13+
it('stops the loop after getting the stop signal', async () => {
14+
const fn = async () => ({ shouldContinueRunning: false });
15+
const fnSpy = jest
16+
.spyOn({ fn }, 'fn')
17+
.mockImplementationOnce(async () => ({ shouldContinueRunning: true }))
18+
.mockImplementationOnce(async () => ({ shouldContinueRunning: true }))
19+
.mockImplementationOnce(async () => ({ shouldContinueRunning: false }));
20+
await runInLoop(fnSpy as any, { logger });
21+
expect(fnSpy).toHaveBeenCalledTimes(3);
22+
});
23+
});

src/run-in-loop/index.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ export interface RunInLoopOptions {
4545
initialDelayMs?: number;
4646
}
4747

48-
export const runInLoop = async (fn: () => Promise<void>, options: RunInLoopOptions) => {
48+
export const runInLoop = async (
49+
fn: () => Promise<{ shouldContinueRunning: boolean } | void>,
50+
options: RunInLoopOptions
51+
) => {
4952
const {
5053
logger,
5154
logLabel,
@@ -73,7 +76,7 @@ export const runInLoop = async (fn: () => Promise<void>, options: RunInLoopOptio
7376

7477
if (enabled) {
7578
const context = logLabel ? { executionId, label: logLabel } : { executionId };
76-
await logger.runWithContext(context, async () => {
79+
const shouldContinueRunning = await logger.runWithContext(context, async () => {
7780
const goRes = await go(fn, hardTimeoutMs ? { totalTimeoutMs: hardTimeoutMs } : {}); // NOTE: This is a safety net to prevent the loop from hanging
7881
if (!goRes.success) {
7982
logger.error(`Unexpected runInLoop error`, goRes.error);
@@ -85,7 +88,14 @@ export const runInLoop = async (fn: () => Promise<void>, options: RunInLoopOptio
8588
} else {
8689
logger.info(`Execution finished`, { executionTimeMs });
8790
}
91+
92+
return goRes.data?.shouldContinueRunning === false ? false : true;
8893
});
94+
95+
// Stop loop execution if the callback return value indicates it should stop
96+
if (!shouldContinueRunning) {
97+
break;
98+
}
8999
} else {
90100
// If the bot is disabled, we still want to run the loop to prevent the process from hanging. We also want to
91101
// sleep according to the wait time logic.

0 commit comments

Comments
 (0)