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:
Michael Auerswald
2023-02-17 10:54:07 +01:00
committed by GitHub
parent 3a9c257f55
commit d143f3f2ec
71 changed files with 1245 additions and 307 deletions
@@ -4,14 +4,17 @@ import { LoggerProxy, MessageEventBusDestinationTypeNames } from 'n8n-workflow';
import * as Db from '@/Db';
import type { AbstractEventMessage } from '../EventMessageClasses/AbstractEventMessage';
import type { EventMessageTypes } from '../EventMessageClasses';
import { eventBus } from '..';
import type { DeleteResult, InsertResult } from 'typeorm';
import type { EventMessageConfirmSource } from '../EventMessageClasses/EventMessageConfirm';
import type { MessageEventBus, MessageWithCallback } from '../MessageEventBus/MessageEventBus';
export abstract class MessageEventBusDestination implements MessageEventBusDestinationOptions {
// Since you can't have static abstract functions - this just serves as a reminder that you need to implement these. Please.
// static abstract deserialize(): MessageEventBusDestination | null;
readonly id: string;
readonly eventBusInstance: MessageEventBus;
__type: MessageEventBusDestinationTypeNames;
label: string;
@@ -24,7 +27,8 @@ export abstract class MessageEventBusDestination implements MessageEventBusDesti
anonymizeAuditMessages: boolean;
constructor(options: MessageEventBusDestinationOptions) {
constructor(eventBusInstance: MessageEventBus, options: MessageEventBusDestinationOptions) {
this.eventBusInstance = eventBusInstance;
this.id = !options.id || options.id.length !== 36 ? uuid() : options.id;
this.__type = options.__type ?? MessageEventBusDestinationTypeNames.abstract;
this.label = options.label ?? 'Log Destination';
@@ -37,15 +41,21 @@ export abstract class MessageEventBusDestination implements MessageEventBusDesti
startListening() {
if (this.enabled) {
eventBus.on(this.getId(), async (msg: EventMessageTypes) => {
await this.receiveFromEventBus(msg);
});
this.eventBusInstance.on(
this.getId(),
async (
msg: EventMessageTypes,
confirmCallback: (message: EventMessageTypes, src: EventMessageConfirmSource) => void,
) => {
await this.receiveFromEventBus({ msg, confirmCallback });
},
);
LoggerProxy.debug(`${this.id} listener started`);
}
}
stopListening() {
eventBus.removeAllListeners(this.getId());
this.eventBusInstance.removeAllListeners(this.getId());
}
enable() {
@@ -81,7 +91,6 @@ export abstract class MessageEventBusDestination implements MessageEventBusDesti
skipUpdateIfNoValuesChanged: true,
conflictPaths: ['id'],
});
Db.collections.EventDestinations.createQueryBuilder().insert().into('something').onConflict('');
return dbResult;
}
@@ -105,7 +114,7 @@ export abstract class MessageEventBusDestination implements MessageEventBusDesti
};
}
abstract receiveFromEventBus(msg: AbstractEventMessage): Promise<boolean>;
abstract receiveFromEventBus(emitterPayload: MessageWithCallback): Promise<boolean>;
toString() {
return JSON.stringify(this.serialize());