fix(core): Prevent re-entry during workflow activation (#17965)

This commit is contained in:
Iván Ovejero
2025-08-04 20:43:18 +02:00
committed by GitHub
parent 642e68e345
commit e8dad4e030
2 changed files with 43 additions and 14 deletions

View File

@@ -148,4 +148,21 @@ describe('ActiveWorkflowManager', () => {
);
});
});
describe('addActiveWorkflows', () => {
test('should prevent concurrent activations', async () => {
const getAllActiveIds = jest.spyOn(workflowRepository, 'getAllActiveIds');
workflowRepository.getAllActiveIds.mockImplementation(
async () => await new Promise((resolve) => setTimeout(() => resolve(['workflow-1']), 50)),
);
await Promise.all([
activeWorkflowManager.addActiveWorkflows('init'),
activeWorkflowManager.addActiveWorkflows('leadershipChange'),
]);
expect(getAllActiveIds).toHaveBeenCalledTimes(1);
});
});
});

View File

@@ -418,11 +418,20 @@ export class ActiveWorkflowManager {
executeErrorWorkflow(workflowData, fullRunData, mode);
}
private isActivationInProgress = false;
/**
* Register as active in memory all workflows stored as `active`,
* only on instance init or (in multi-main setup) on leadership change.
*/
async addActiveWorkflows(activationMode: 'init' | 'leadershipChange') {
if (this.isActivationInProgress) {
this.logger.debug(`Skipping activation - already in progress for mode: ${activationMode}`);
return;
}
this.isActivationInProgress = true;
try {
const dbWorkflowIds = await this.workflowRepository.getAllActiveIds();
if (dbWorkflowIds.length === 0) return;
@@ -442,6 +451,9 @@ export class ActiveWorkflowManager {
}
this.logger.debug('Finished activating all workflows');
} finally {
this.isActivationInProgress = false;
}
}
private async activateWorkflow(