mirror of
https://github.com/n8n-io/n8n.git
synced 2026-10-17 05:29:44 +02:00
fix(core): Remove unused N8N_SCHEDULER_MIN_INTERVAL setting (#41194)
This commit is contained in:
parent
154cd63bbc
commit
c839d6cd49
|
|
@ -32,7 +32,6 @@ describe('SchedulerConfig', () => {
|
|||
expect(scheduler.retentionSeconds).toBe(24 * 60 * 60);
|
||||
expect(scheduler.failedRetentionSeconds).toBe(7 * 24 * 60 * 60);
|
||||
expect(scheduler.retentionIntervalSeconds).toBe(60 * 60);
|
||||
expect(scheduler.minIntervalSeconds).toBe(0);
|
||||
expect(scheduler.jitterRatio).toBe(0.1);
|
||||
expect(scheduler.materializationTimeoutSeconds).toBe(60);
|
||||
expect(scheduler.executorTimeoutSeconds).toBe(60);
|
||||
|
|
@ -74,7 +73,6 @@ describe('SchedulerConfig', () => {
|
|||
vi.stubEnv('N8N_SCHEDULER_RETENTION', '43200');
|
||||
vi.stubEnv('N8N_SCHEDULER_FAILED_RETENTION', '86400');
|
||||
vi.stubEnv('N8N_SCHEDULER_RETENTION_INTERVAL', '600');
|
||||
vi.stubEnv('N8N_SCHEDULER_MIN_INTERVAL', '15');
|
||||
vi.stubEnv('N8N_SCHEDULER_JITTER_RATIO', '0.25');
|
||||
vi.stubEnv('N8N_SCHEDULER_MATERIALIZATION_TIMEOUT', '30');
|
||||
vi.stubEnv('N8N_SCHEDULER_EXECUTOR_TIMEOUT', '15');
|
||||
|
|
@ -97,7 +95,6 @@ describe('SchedulerConfig', () => {
|
|||
expect(scheduler.retentionSeconds).toBe(43200);
|
||||
expect(scheduler.failedRetentionSeconds).toBe(86400);
|
||||
expect(scheduler.retentionIntervalSeconds).toBe(600);
|
||||
expect(scheduler.minIntervalSeconds).toBe(15);
|
||||
expect(scheduler.jitterRatio).toBe(0.25);
|
||||
expect(scheduler.materializationTimeoutSeconds).toBe(30);
|
||||
expect(scheduler.executorTimeoutSeconds).toBe(15);
|
||||
|
|
@ -128,13 +125,5 @@ describe('SchedulerConfig', () => {
|
|||
|
||||
expect(scheduler.taskTimeoutSeconds).toBe(300);
|
||||
});
|
||||
|
||||
it('should allow disabling the min-interval clamp with 0', () => {
|
||||
vi.stubEnv('N8N_SCHEDULER_MIN_INTERVAL', '0');
|
||||
|
||||
const { scheduler } = Container.get(GlobalConfig);
|
||||
|
||||
expect(scheduler.minIntervalSeconds).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -4,12 +4,6 @@ import { z } from 'zod';
|
|||
import { Config, Env } from '../decorators';
|
||||
import { positiveIntSchema } from '../schemas';
|
||||
|
||||
/**
|
||||
* Allows 0 (the clamp disabled) in addition to any positive value. Used for a
|
||||
* setting where 0 is a meaningful "off", not just a smaller number.
|
||||
*/
|
||||
const nonNegativeIntSchema = z.number({ coerce: true }).int().nonnegative();
|
||||
|
||||
/**
|
||||
* A jitter ratio: a fraction in [0, 1). 0 disables jitter; 1 or above would
|
||||
* allow a zero or negative delay between ticks, so they are rejected.
|
||||
|
|
@ -233,18 +227,6 @@ export class SchedulerConfig {
|
|||
@Env('N8N_SCHEDULER_JITTER_RATIO', jitterRatioSchema)
|
||||
jitterRatio: number = 0.1;
|
||||
|
||||
/**
|
||||
* The smallest gap, in seconds, allowed between consecutive runs of the same
|
||||
* schedule. A schedule set to run more often than this is slowed down to this
|
||||
* gap. Defaults to 0, which disables the limit and honours whatever interval
|
||||
* each schedule specifies.
|
||||
*
|
||||
* Set it to put a floor on how frequently any schedule can run, for example to
|
||||
* stop a misconfigured every-second schedule from overloading the instance.
|
||||
*/
|
||||
@Env('N8N_SCHEDULER_MIN_INTERVAL', nonNegativeIntSchema)
|
||||
minIntervalSeconds: number = 0;
|
||||
|
||||
/**
|
||||
* How a Schedule Trigger node's "every N seconds/minutes" schedules run under
|
||||
* the durable scheduler. Defaults to `new`.
|
||||
|
|
|
|||
|
|
@ -513,7 +513,6 @@ describe('GlobalConfig', () => {
|
|||
retentionIntervalSeconds: 3600,
|
||||
retentionTimeoutSeconds: 300,
|
||||
jitterRatio: 0.1,
|
||||
minIntervalSeconds: 0,
|
||||
maxConcurrentPasses: 10,
|
||||
triggerNodeMode: 'new',
|
||||
enabledForPollTriggers: false,
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ describe('DurableScheduler', () => {
|
|||
instanceType = 'main',
|
||||
dbType = 'sqlite',
|
||||
materializationIntervalSeconds = 10,
|
||||
minIntervalSeconds = 0,
|
||||
executorIntervalSeconds = 5,
|
||||
materializationWindowSeconds = 60,
|
||||
misfireGraceSeconds = 60,
|
||||
|
|
@ -72,7 +71,6 @@ describe('DurableScheduler', () => {
|
|||
executorIntervalSeconds,
|
||||
jitterRatio: 0.1,
|
||||
materializationIntervalSeconds,
|
||||
minIntervalSeconds,
|
||||
materializationWindowSeconds,
|
||||
misfireGraceSeconds,
|
||||
enabledForPollTriggers,
|
||||
|
|
@ -137,8 +135,8 @@ describe('DurableScheduler', () => {
|
|||
|
||||
describe('drain rate warning', () => {
|
||||
it('warns when a pass cannot drain the fastest possible schedule before the next one is due', () => {
|
||||
// maxPerJob is 1000: a schedule as fast as this instance allows (the default
|
||||
// floor of one second) can outrun a 1001s materialization interval.
|
||||
// maxPerJob is 1000: a one-second schedule can outrun a 1001s materialization
|
||||
// interval.
|
||||
const { logger } = makeScheduler({ materializationIntervalSeconds: 1001 });
|
||||
|
||||
expect(logger.warn).toHaveBeenCalledWith(
|
||||
|
|
@ -155,20 +153,6 @@ describe('DurableScheduler', () => {
|
|||
expect.anything(),
|
||||
);
|
||||
});
|
||||
|
||||
it('scales the threshold by an operator-configured minimum interval floor', () => {
|
||||
// A 60s floor makes 1001s safe again: even the fastest schedule now
|
||||
// produces at most one occurrence per 60s, well within maxPerJob's reach.
|
||||
const { logger } = makeScheduler({
|
||||
materializationIntervalSeconds: 1001,
|
||||
minIntervalSeconds: 60,
|
||||
});
|
||||
|
||||
expect(logger.warn).not.toHaveBeenCalledWith(
|
||||
expect.stringContaining('materialization interval'),
|
||||
expect.anything(),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('misfire grace warning', () => {
|
||||
|
|
|
|||
|
|
@ -179,15 +179,13 @@ function warnOnMisfireGrace(logger: Logger, config: GlobalConfig['scheduler']):
|
|||
* running.
|
||||
*/
|
||||
function warnOnDrainRate(logger: Logger, config: GlobalConfig['scheduler']): void {
|
||||
const { materializationIntervalSeconds, minIntervalSeconds } = config;
|
||||
// The fastest a schedule can legally fire: the operator's floor if they set
|
||||
// one, otherwise the fastest an interval can be at all.
|
||||
const fastestIntervalSeconds = minIntervalSeconds > 0 ? minIntervalSeconds : 1;
|
||||
const drainSeconds = DEFAULT_MATERIALIZER_OPTIONS.maxPerJob * fastestIntervalSeconds;
|
||||
const { materializationIntervalSeconds } = config;
|
||||
// The fastest a schedule can fire is once per second.
|
||||
const drainSeconds = DEFAULT_MATERIALIZER_OPTIONS.maxPerJob;
|
||||
if (materializationIntervalSeconds > drainSeconds) {
|
||||
logger.warn(
|
||||
'Scheduler materialization interval is long enough that a pass may never fully drain the busiest possible schedule; under the coalesce misfire policy such a schedule could stop producing catch-up runs entirely',
|
||||
{ materializationIntervalSeconds, fastestIntervalSeconds },
|
||||
{ materializationIntervalSeconds },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user