mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 10:02:05 +00:00
feat(core): Add execution runData recovery and status field (#5112)
* adds ExecutionEvents view modal to ExecutionList * fix time rendering and remove wf column * checks for unfinished executions and fails them * prevent re-setting stoppedAt for execution * some cleanup / manually create rundata after crash * quicksave * remove Threads lib, log worker rewrite * cleanup comment * fix sentry destination return value * test for tests... * run tests with single worker * fix tests * remove console log * add endpoint for execution data recovery * lint cleanup and some refactoring * fix accidental recursion * remove cyclic imports * add rundata recovery to Workflowrunner * remove comments * cleanup and refactor * adds a status field to executions * setExecutionStatus on queued worker * fix onWorkflowPostExecute * set waiting from worker * get crashed status into frontend * remove comment * merge fix * cleanup * catch empty rundata in recovery * refactor IExecutionsSummary and inject nodeExecution Errors * reduce default event log size to 10mb from 100mb * add per node execution status * lint fix * merge and lint fix * phrasing change * improve preview rendering and messaging * remove debug * Improve partial rundata recovery * fix labels * fix line through * send manual rundata to ui at crash * some type and msg push fixes * improve recovered item rendering in preview * update workflowStatistics on recover * merge fix * review fixes * merge fix * notify eventbus when ui is back up * add a small timeout to make sure the UI is back up * increase reconnect timeout to 30s * adjust recover timeout and ui connection lost msg * do not stop execution in editor after x reconnects * add executionRecovered push event * fix recovered connection not green * remove reconnect toast and merge existing rundata * merge editor and recovered data for own mode
This commit is contained in:
committed by
GitHub
parent
3a9c257f55
commit
d143f3f2ec
@@ -22,6 +22,7 @@ import { MessageEventBusDestinationWebhook } from '@/eventbus/MessageEventBusDes
|
||||
import { MessageEventBusDestinationSentry } from '@/eventbus/MessageEventBusDestination/MessageEventBusDestinationSentry.ee';
|
||||
import { EventMessageAudit } from '@/eventbus/EventMessageClasses/EventMessageAudit';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { EventNamesTypes } from '../../src/eventbus/EventMessageClasses';
|
||||
|
||||
jest.unmock('@/eventbus/MessageEventBus/MessageEventBus');
|
||||
jest.mock('axios');
|
||||
@@ -62,12 +63,6 @@ const testSentryDestination: MessageEventBusDestinationSentryOptions = {
|
||||
subscribedEvents: ['n8n.test.message', 'n8n.audit.user.updated'],
|
||||
};
|
||||
|
||||
async function cleanLogs() {
|
||||
eventBus.logWriter.cleanAllLogs();
|
||||
const allMessages = await eventBus.getEventsAll();
|
||||
expect(allMessages.length).toBe(0);
|
||||
}
|
||||
|
||||
async function confirmIdInAll(id: string) {
|
||||
const sent = await eventBus.getEventsAll();
|
||||
expect(sent.length).toBeGreaterThan(0);
|
||||
@@ -106,13 +101,13 @@ beforeAll(async () => {
|
||||
config.set('eventBus.logWriter.logBaseName', 'n8n-test-logwriter');
|
||||
config.set('eventBus.logWriter.keepLogCount', '1');
|
||||
config.set('enterprise.features.logStreaming', true);
|
||||
|
||||
await eventBus.initialize();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
config.set('userManagement.disabled', false);
|
||||
config.set('userManagement.isInstanceOwnerSetUp', true);
|
||||
config.set('enterprise.features.logStreaming', false);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
@@ -127,7 +122,10 @@ test('should have a running logwriter process', () => {
|
||||
});
|
||||
|
||||
test('should have logwriter log messages', async () => {
|
||||
const testMessage = new EventMessageGeneric({ eventName: 'n8n.test.message', id: uuid() });
|
||||
const testMessage = new EventMessageGeneric({
|
||||
eventName: 'n8n.test.message' as EventNamesTypes,
|
||||
id: uuid(),
|
||||
});
|
||||
await eventBus.send(testMessage);
|
||||
await new Promise((resolve) => {
|
||||
eventBus.logWriter.worker?.once('message', async (msg: { command: string; data: any }) => {
|
||||
@@ -176,10 +174,13 @@ test('GET /eventbus/destination all returned destinations should exist in eventb
|
||||
}
|
||||
});
|
||||
|
||||
// this test (presumably the mocking) is causing the test suite to randomly fail
|
||||
test.skip('should send message to syslog', async () => {
|
||||
const testMessage = new EventMessageGeneric({ eventName: 'n8n.test.message', id: uuid() });
|
||||
const testMessage = new EventMessageGeneric({
|
||||
eventName: 'n8n.test.message' as EventNamesTypes,
|
||||
id: uuid(),
|
||||
});
|
||||
config.set('enterprise.features.logStreaming', true);
|
||||
// await cleanLogs();
|
||||
|
||||
const syslogDestination = eventBus.destinations[
|
||||
testSyslogDestination.id!
|
||||
@@ -217,11 +218,10 @@ test.skip('should send message to syslog', async () => {
|
||||
|
||||
test.skip('should confirm send message if there are no subscribers', async () => {
|
||||
const testMessageUnsubscribed = new EventMessageGeneric({
|
||||
eventName: 'n8n.test.unsub',
|
||||
eventName: 'n8n.test.unsub' as EventNamesTypes,
|
||||
id: uuid(),
|
||||
});
|
||||
config.set('enterprise.features.logStreaming', true);
|
||||
// await cleanLogs();
|
||||
|
||||
const syslogDestination = eventBus.destinations[
|
||||
testSyslogDestination.id!
|
||||
@@ -229,11 +229,6 @@ test.skip('should confirm send message if there are no subscribers', async () =>
|
||||
|
||||
syslogDestination.enable();
|
||||
|
||||
const mockedSyslogClientLog = jest.spyOn(syslogDestination.client, 'log');
|
||||
mockedSyslogClientLog.mockImplementation((_m, _options, _cb) => {
|
||||
return syslogDestination.client;
|
||||
});
|
||||
|
||||
await eventBus.send(testMessageUnsubscribed);
|
||||
|
||||
await new Promise((resolve) => {
|
||||
@@ -244,7 +239,6 @@ test.skip('should confirm send message if there are no subscribers', async () =>
|
||||
await confirmIdInAll(testMessageUnsubscribed.id);
|
||||
} else if (msg.command === 'confirmMessageSent') {
|
||||
await confirmIdSent(testMessageUnsubscribed.id);
|
||||
expect(mockedSyslogClientLog).toHaveBeenCalled();
|
||||
syslogDestination.disable();
|
||||
eventBus.logWriter.worker?.removeListener('message', handler002);
|
||||
resolve(true);
|
||||
@@ -264,7 +258,6 @@ test('should anonymize audit message to syslog ', async () => {
|
||||
id: uuid(),
|
||||
});
|
||||
config.set('enterprise.features.logStreaming', true);
|
||||
// await cleanLogs();
|
||||
|
||||
const syslogDestination = eventBus.destinations[
|
||||
testSyslogDestination.id!
|
||||
@@ -322,9 +315,11 @@ test('should anonymize audit message to syslog ', async () => {
|
||||
});
|
||||
|
||||
test('should send message to webhook ', async () => {
|
||||
const testMessage = new EventMessageGeneric({ eventName: 'n8n.test.message', id: uuid() });
|
||||
const testMessage = new EventMessageGeneric({
|
||||
eventName: 'n8n.test.message' as EventNamesTypes,
|
||||
id: uuid(),
|
||||
});
|
||||
config.set('enterprise.features.logStreaming', true);
|
||||
// await cleanLogs();
|
||||
|
||||
const webhookDestination = eventBus.destinations[
|
||||
testWebhookDestination.id!
|
||||
@@ -355,9 +350,11 @@ test('should send message to webhook ', async () => {
|
||||
});
|
||||
|
||||
test('should send message to sentry ', async () => {
|
||||
const testMessage = new EventMessageGeneric({ eventName: 'n8n.test.message', id: uuid() });
|
||||
const testMessage = new EventMessageGeneric({
|
||||
eventName: 'n8n.test.message' as EventNamesTypes,
|
||||
id: uuid(),
|
||||
});
|
||||
config.set('enterprise.features.logStreaming', true);
|
||||
// await cleanLogs();
|
||||
|
||||
const sentryDestination = eventBus.destinations[
|
||||
testSentryDestination.id!
|
||||
|
||||
Reference in New Issue
Block a user