mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 01:56:46 +00:00
feat(core): Implement task timeouts and heartbeats for runners (no-changelog) (#11690)
Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <aditya@netroy.in>
This commit is contained in:
@@ -1,4 +1,16 @@
|
||||
import { Config, Env } from '@n8n/config';
|
||||
import { Config, Env, Nested } from '@n8n/config';
|
||||
|
||||
@Config
|
||||
class HealthcheckServerConfig {
|
||||
@Env('N8N_RUNNERS_SERVER_ENABLED')
|
||||
enabled: boolean = false;
|
||||
|
||||
@Env('N8N_RUNNERS_SERVER_HOST')
|
||||
host: string = '127.0.0.1';
|
||||
|
||||
@Env('N8N_RUNNERS_SERVER_PORT')
|
||||
port: number = 5680;
|
||||
}
|
||||
|
||||
@Config
|
||||
export class BaseRunnerConfig {
|
||||
@@ -13,4 +25,7 @@ export class BaseRunnerConfig {
|
||||
|
||||
@Env('N8N_RUNNERS_MAX_CONCURRENCY')
|
||||
maxConcurrency: number = 5;
|
||||
|
||||
@Nested
|
||||
healthcheckServer!: HealthcheckServerConfig;
|
||||
}
|
||||
|
||||
38
packages/@n8n/task-runner/src/healthcheck-server.ts
Normal file
38
packages/@n8n/task-runner/src/healthcheck-server.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { ApplicationError } from 'n8n-workflow';
|
||||
import { createServer } from 'node:http';
|
||||
|
||||
export class HealthcheckServer {
|
||||
private server = createServer((_, res) => {
|
||||
res.writeHead(200);
|
||||
res.end('OK');
|
||||
});
|
||||
|
||||
async start(host: string, port: number) {
|
||||
return await new Promise<void>((resolve, reject) => {
|
||||
const portInUseErrorHandler = (error: NodeJS.ErrnoException) => {
|
||||
if (error.code === 'EADDRINUSE') {
|
||||
reject(new ApplicationError(`Port ${port} is already in use`));
|
||||
} else {
|
||||
reject(error);
|
||||
}
|
||||
};
|
||||
|
||||
this.server.on('error', portInUseErrorHandler);
|
||||
|
||||
this.server.listen(port, host, () => {
|
||||
this.server.removeListener('error', portInUseErrorHandler);
|
||||
console.log(`Healthcheck server listening on ${host}, port ${port}`);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async stop() {
|
||||
return await new Promise<void>((resolve, reject) => {
|
||||
this.server.close((error) => {
|
||||
if (error) reject(error);
|
||||
else resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,10 @@ import Container from 'typedi';
|
||||
|
||||
import { MainConfig } from './config/main-config';
|
||||
import type { ErrorReporter } from './error-reporter';
|
||||
import type { HealthcheckServer } from './healthcheck-server';
|
||||
import { JsTaskRunner } from './js-task-runner/js-task-runner';
|
||||
|
||||
let healthcheckServer: HealthcheckServer | undefined;
|
||||
let runner: JsTaskRunner | undefined;
|
||||
let isShuttingDown = false;
|
||||
let errorReporter: ErrorReporter | undefined;
|
||||
@@ -22,6 +24,7 @@ function createSignalHandler(signal: string) {
|
||||
if (runner) {
|
||||
await runner.stop();
|
||||
runner = undefined;
|
||||
void healthcheckServer?.stop();
|
||||
}
|
||||
|
||||
if (errorReporter) {
|
||||
@@ -49,6 +52,14 @@ void (async function start() {
|
||||
|
||||
runner = new JsTaskRunner(config);
|
||||
|
||||
const { enabled, host, port } = config.baseRunnerConfig.healthcheckServer;
|
||||
|
||||
if (enabled) {
|
||||
const { HealthcheckServer } = await import('./healthcheck-server');
|
||||
healthcheckServer = new HealthcheckServer();
|
||||
await healthcheckServer.start(host, port);
|
||||
}
|
||||
|
||||
process.on('SIGINT', createSignalHandler('SIGINT'));
|
||||
process.on('SIGTERM', createSignalHandler('SIGTERM'));
|
||||
})().catch((e) => {
|
||||
|
||||
Reference in New Issue
Block a user