mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-21 20:00:02 +00:00
fix(core): Ensure only leader handles waiting executions (#9014)
This commit is contained in:
@@ -7,8 +7,9 @@ import { Container, Service } from 'typedi';
|
||||
import type { IExecutionsStopData, IWorkflowExecutionDataProcess } from '@/Interfaces';
|
||||
import { WorkflowRunner } from '@/WorkflowRunner';
|
||||
import { ExecutionRepository } from '@db/repositories/execution.repository';
|
||||
import { OwnershipService } from './services/ownership.service';
|
||||
import { OwnershipService } from '@/services/ownership.service';
|
||||
import { Logger } from '@/Logger';
|
||||
import { OrchestrationService } from '@/services/orchestration.service';
|
||||
|
||||
@Service()
|
||||
export class WaitTracker {
|
||||
@@ -26,7 +27,22 @@ export class WaitTracker {
|
||||
private readonly executionRepository: ExecutionRepository,
|
||||
private readonly ownershipService: OwnershipService,
|
||||
private readonly workflowRunner: WorkflowRunner,
|
||||
readonly orchestrationService: OrchestrationService,
|
||||
) {
|
||||
const { isLeader, isMultiMainSetupEnabled, multiMainSetup } = orchestrationService;
|
||||
|
||||
if (isLeader) this.startTracking();
|
||||
|
||||
if (isMultiMainSetupEnabled) {
|
||||
multiMainSetup
|
||||
.on('leader-takeover', () => this.startTracking())
|
||||
.on('leader-stepdown', () => this.stopTracking());
|
||||
}
|
||||
}
|
||||
|
||||
startTracking() {
|
||||
this.logger.debug('Wait tracker started tracking waiting executions');
|
||||
|
||||
// Poll every 60 seconds a list of upcoming executions
|
||||
this.mainTimer = setInterval(() => {
|
||||
void this.getWaitingExecutions();
|
||||
@@ -174,7 +190,9 @@ export class WaitTracker {
|
||||
});
|
||||
}
|
||||
|
||||
shutdown() {
|
||||
stopTracking() {
|
||||
this.logger.debug('Wait tracker shutting down');
|
||||
|
||||
clearInterval(this.mainTimer);
|
||||
Object.keys(this.waitingExecutions).forEach((executionId) => {
|
||||
clearTimeout(this.waitingExecutions[executionId].timer);
|
||||
|
||||
@@ -94,7 +94,7 @@ export class Start extends BaseCommand {
|
||||
// Stop with trying to activate workflows that could not be activated
|
||||
this.activeWorkflowRunner.removeAllQueuedWorkflowActivations();
|
||||
|
||||
Container.get(WaitTracker).shutdown();
|
||||
Container.get(WaitTracker).stopTracking();
|
||||
|
||||
await this.externalHooks?.run('n8n.stop', []);
|
||||
|
||||
|
||||
@@ -39,6 +39,9 @@ export class OrchestrationService {
|
||||
return config.getEnv('redis.queueModeId');
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this instance is the leader in a multi-main setup. Always `true` in single-main setup.
|
||||
*/
|
||||
get isLeader() {
|
||||
return config.getEnv('multiMainSetup.instanceType') === 'leader';
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ export class MultiMainSetup extends EventEmitter {
|
||||
if (config.getEnv('multiMainSetup.instanceType') === 'leader') {
|
||||
config.set('multiMainSetup.instanceType', 'follower');
|
||||
|
||||
this.emit('leader-stepdown'); // lost leadership - stop triggers, pollers, pruning
|
||||
this.emit('leader-stepdown'); // lost leadership - stop triggers, pollers, pruning, wait-tracking
|
||||
|
||||
EventReporter.info('[Multi-main setup] Leader failed to renew leader key');
|
||||
}
|
||||
@@ -97,7 +97,7 @@ export class MultiMainSetup extends EventEmitter {
|
||||
|
||||
await this.redisPublisher.setExpiration(this.leaderKey, this.leaderKeyTtl);
|
||||
|
||||
this.emit('leader-takeover'); // gained leadership - start triggers, pollers, pruning
|
||||
this.emit('leader-takeover'); // gained leadership - start triggers, pollers, pruning, wait-tracking
|
||||
} else {
|
||||
config.set('multiMainSetup.instanceType', 'follower');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user