feat(core): Detect restart loop in a task runner process (no-changelog) (#12003)

Co-authored-by: Iván Ovejero <ivov.src@gmail.com>
This commit is contained in:
Tomi Turtiainen
2024-12-09 13:11:29 +02:00
committed by GitHub
parent 00897f6634
commit 516f3b7b4b
6 changed files with 205 additions and 2 deletions

View File

@@ -1,4 +1,5 @@
import { TaskRunnersConfig } from '@n8n/config';
import { mock } from 'jest-mock-extended';
import Container from 'typedi';
import { MissingAuthTokenError } from '@/runners/errors/missing-auth-token.error';
@@ -32,7 +33,7 @@ describe('TaskRunnerModule in external mode', () => {
runnerConfig.enabled = true;
runnerConfig.authToken = '';
const module = new TaskRunnerModule(runnerConfig);
const module = new TaskRunnerModule(mock(), runnerConfig);
await expect(module.start()).rejects.toThrowError(MissingAuthTokenError);
});

View File

@@ -3,6 +3,7 @@ import Container from 'typedi';
import { TaskRunnerWsServer } from '@/runners/runner-ws-server';
import { TaskBroker } from '@/runners/task-broker.service';
import { TaskRunnerProcess } from '@/runners/task-runner-process';
import { TaskRunnerProcessRestartLoopDetector } from '@/runners/task-runner-process-restart-loop-detector';
import { retryUntil } from '@test-integration/retry-until';
import { setupBrokerTestServer } from '@test-integration/utils/task-broker-test-server';
@@ -84,4 +85,33 @@ describe('TaskRunnerProcess', () => {
expect(getNumRegisteredRunners()).toBe(1);
expect(runnerProcess.pid).not.toBe(processId);
});
it('should work together with restart loop detector', async () => {
// Arrange
const restartLoopDetector = new TaskRunnerProcessRestartLoopDetector(runnerProcess);
let restartLoopDetectedEventEmitted = false;
restartLoopDetector.once('restart-loop-detected', () => {
restartLoopDetectedEventEmitted = true;
});
// Act
await runnerProcess.start();
// Simulate a restart loop
for (let i = 0; i < 5; i++) {
await retryUntil(() => {
expect(runnerProcess.pid).toBeDefined();
});
// @ts-expect-error private property
runnerProcess.process?.kill();
await new Promise((resolve) => {
runnerProcess.once('exit', resolve);
});
}
// Assert
expect(restartLoopDetectedEventEmitted).toBe(true);
});
});