fix(core): Minor improvements to multi-main setup (no-changelog) (#8012)

- Move webhook, poller and trigger activation logs closer to activation
event
- Enrich response of `/debug/multi-main-setup`
- Ensure workflow updates broadcast activation state changes only if
state changed
- Fix bug on workflow activation after leadership change
- Ensure debug controller is not available in production

---------

Co-authored-by: Omar Ajoue <krynble@gmail.com>
This commit is contained in:
Iván Ovejero
2023-12-27 16:55:01 +01:00
committed by GitHub
parent f69ddcd796
commit 2c6ffb0153
6 changed files with 93 additions and 23 deletions

View File

@@ -25,22 +25,39 @@ describe('DebugController', () => {
describe('GET /debug/multi-main-setup', () => {
test('should return multi-main setup details', async () => {
const workflowId = generateNanoId();
const activeWorkflows = [{ id: workflowId, name: randomName() }] as WorkflowEntity[];
const webhooks = [{ id: workflowId, name: randomName() }] as WorkflowEntity[];
const triggersAndPollers = [{ id: workflowId, name: randomName() }] as WorkflowEntity[];
const activationErrors = { [workflowId]: 'Failed to activate' };
const instanceId = 'main-71JdWtq306epIFki';
const leaderKey = 'some-leader-key';
workflowRepository.find.mockResolvedValue(activeWorkflows);
const createQueryBuilder = {
select: () => createQueryBuilder,
innerJoin: () => createQueryBuilder,
execute: () => webhooks,
};
workflowRepository.find.mockResolvedValue(triggersAndPollers);
activeWorkflowRunner.allActiveInMemory.mockReturnValue([workflowId]);
activeWorkflowRunner.getAllWorkflowActivationErrors.mockResolvedValue(activationErrors);
jest
.spyOn(workflowRepository, 'createQueryBuilder')
.mockImplementation(() => createQueryBuilder);
jest.spyOn(MultiMainSetup.prototype, 'instanceId', 'get').mockReturnValue(instanceId);
jest.spyOn(MultiMainSetup.prototype, 'fetchLeaderKey').mockResolvedValue('some-leader-key');
jest.spyOn(MultiMainSetup.prototype, 'fetchLeaderKey').mockResolvedValue(leaderKey);
jest.spyOn(MultiMainSetup.prototype, 'isLeader', 'get').mockReturnValue(true);
const response = await ownerAgent.get('/debug/multi-main-setup').expect(200);
expect(response.body.data).toMatchObject({
instanceId,
leaderKey: 'some-leader-key',
activeWorkflows,
leaderKey,
isLeader: true,
activeWorkflows: {
webhooks,
triggersAndPollers,
},
activationErrors,
});
});

View File

@@ -9,14 +9,17 @@ import { SharedWorkflowRepository } from '@/databases/repositories/sharedWorkflo
import { mock } from 'jest-mock-extended';
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
import { Telemetry } from '@/telemetry';
import { MultiMainSetup } from '@/services/orchestration/main/MultiMainSetup.ee';
let workflowService: WorkflowService;
let activeWorkflowRunner: ActiveWorkflowRunner;
let multiMainSetup: MultiMainSetup;
beforeAll(async () => {
await testDb.init();
activeWorkflowRunner = mockInstance(ActiveWorkflowRunner);
multiMainSetup = mockInstance(MultiMainSetup);
mockInstance(Telemetry);
workflowService = new WorkflowService(
@@ -29,7 +32,7 @@ beforeAll(async () => {
mock(),
mock(),
mock(),
mock(),
multiMainSetup,
mock(),
mock(),
mock(),
@@ -82,4 +85,27 @@ describe('update()', () => {
expect(addSpy).not.toHaveBeenCalled();
});
test('should broadcast active workflow state change if state changed', async () => {
const owner = await createOwner();
const workflow = await createWorkflow({ active: true }, owner);
const broadcastSpy = jest.spyOn(multiMainSetup, 'broadcastWorkflowActiveStateChanged');
workflow.active = false;
await workflowService.update(owner, workflow, workflow.id);
expect(broadcastSpy).toHaveBeenCalledTimes(1);
});
test('should not broadcast active workflow state change if state did not change', async () => {
const owner = await createOwner();
const workflow = await createWorkflow({ active: true }, owner);
const broadcastSpy = jest.spyOn(multiMainSetup, 'broadcastWorkflowActiveStateChanged');
await workflowService.update(owner, workflow, workflow.id);
expect(broadcastSpy).not.toHaveBeenCalled();
});
});