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

View File

@@ -4,6 +4,7 @@ import type { EventMessageTypeNames, JsonObject } from 'n8n-workflow';
import { v4 as uuid } from 'uuid';
import type { AbstractEventPayload } from './AbstractEventPayload';
import type { AbstractEventMessageOptions } from './AbstractEventMessageOptions';
import type { EventNamesTypes } from '.';
function modifyUnderscoredKeys(
input: { [key: string]: any },
@@ -85,7 +86,7 @@ export abstract class AbstractEventMessage {
ts: DateTime;
eventName: string;
eventName: EventNamesTypes;
message: string;

View File

@@ -1,12 +1,13 @@
import type { DateTime } from 'luxon';
import type { EventMessageTypeNames } from 'n8n-workflow';
import type { EventNamesTypes } from '.';
import type { AbstractEventPayload } from './AbstractEventPayload';
export interface AbstractEventMessageOptions {
__type?: EventMessageTypeNames;
id?: string;
ts?: DateTime | string;
eventName: string;
eventName: EventNamesTypes;
message?: string;
payload?: AbstractEventPayload;
anonymize?: boolean;

View File

@@ -1,31 +1,9 @@
import { AbstractEventMessage, isEventMessageOptionsWithType } from './AbstractEventMessage';
import type { JsonObject, JsonValue } from 'n8n-workflow';
import { EventMessageTypeNames } from 'n8n-workflow';
import type { JsonObject, JsonValue } from 'n8n-workflow';
import type { AbstractEventPayload } from './AbstractEventPayload';
import type { AbstractEventMessageOptions } from './AbstractEventMessageOptions';
export const eventNamesAudit = [
'n8n.audit.user.signedup',
'n8n.audit.user.updated',
'n8n.audit.user.deleted',
'n8n.audit.user.invited',
'n8n.audit.user.invitation.accepted',
'n8n.audit.user.reinvited',
'n8n.audit.user.email.failed',
'n8n.audit.user.reset.requested',
'n8n.audit.user.reset',
'n8n.audit.user.credentials.created',
'n8n.audit.user.credentials.shared',
'n8n.audit.user.api.created',
'n8n.audit.user.api.deleted',
'n8n.audit.package.installed',
'n8n.audit.package.updated',
'n8n.audit.package.deleted',
'n8n.audit.workflow.created',
'n8n.audit.workflow.deleted',
'n8n.audit.workflow.updated',
] as const;
export type EventNamesAuditType = (typeof eventNamesAudit)[number];
import type { EventNamesAuditType } from '.';
// --------------------------------------
// EventMessage class for Audit events

View File

@@ -3,9 +3,7 @@ import type { JsonObject } from 'n8n-workflow';
import { EventMessageTypeNames } from 'n8n-workflow';
import type { AbstractEventMessageOptions } from './AbstractEventMessageOptions';
import type { AbstractEventPayload } from './AbstractEventPayload';
export const eventNamesNode = ['n8n.node.started', 'n8n.node.finished'] as const;
export type EventNamesNodeType = (typeof eventNamesNode)[number];
import type { EventNamesNodeType } from '.';
// --------------------------------------
// EventMessage class for Node events

View File

@@ -4,14 +4,7 @@ import { EventMessageTypeNames } from 'n8n-workflow';
import type { AbstractEventMessageOptions } from './AbstractEventMessageOptions';
import type { AbstractEventPayload } from './AbstractEventPayload';
import type { IExecutionBase } from '@/Interfaces';
export const eventNamesWorkflow = [
'n8n.workflow.started',
'n8n.workflow.success',
'n8n.workflow.failed',
] as const;
export type EventNamesWorkflowType = (typeof eventNamesWorkflow)[number];
import type { EventNamesWorkflowType } from '.';
// --------------------------------------
// EventMessage class for Workflow events

View File

@@ -1,12 +1,47 @@
import type { EventMessageAudit, EventNamesAuditType } from './EventMessageAudit';
import { eventNamesAudit } from './EventMessageAudit';
import type { EventMessageAudit } from './EventMessageAudit';
import type { EventMessageGeneric } from './EventMessageGeneric';
import type { EventMessageNode, EventNamesNodeType } from './EventMessageNode';
import { eventNamesNode } from './EventMessageNode';
import type { EventMessageWorkflow, EventNamesWorkflowType } from './EventMessageWorkflow';
import { eventNamesWorkflow } from './EventMessageWorkflow';
import type { EventMessageNode } from './EventMessageNode';
import type { EventMessageWorkflow } from './EventMessageWorkflow';
export const eventNamesWorkflow = [
'n8n.workflow.started',
'n8n.workflow.success',
'n8n.workflow.failed',
'n8n.workflow.crashed',
] as const;
export const eventNamesNode = ['n8n.node.started', 'n8n.node.finished'] as const;
export const eventNamesAudit = [
'n8n.audit.user.signedup',
'n8n.audit.user.updated',
'n8n.audit.user.deleted',
'n8n.audit.user.invited',
'n8n.audit.user.invitation.accepted',
'n8n.audit.user.reinvited',
'n8n.audit.user.email.failed',
'n8n.audit.user.reset.requested',
'n8n.audit.user.reset',
'n8n.audit.user.credentials.created',
'n8n.audit.user.credentials.shared',
'n8n.audit.user.api.created',
'n8n.audit.user.api.deleted',
'n8n.audit.package.installed',
'n8n.audit.package.updated',
'n8n.audit.package.deleted',
'n8n.audit.workflow.created',
'n8n.audit.workflow.deleted',
'n8n.audit.workflow.updated',
] as const;
export type EventNamesWorkflowType = (typeof eventNamesWorkflow)[number];
export type EventNamesAuditType = (typeof eventNamesAudit)[number];
export type EventNamesNodeType = (typeof eventNamesNode)[number];
export type EventNamesTypes =
| EventNamesAuditType
| EventNamesWorkflowType
| EventNamesNodeType
| 'n8n.destination.test';
export type EventNamesTypes = EventNamesAuditType | EventNamesWorkflowType | EventNamesNodeType;
export const eventNamesAll = [...eventNamesAudit, ...eventNamesWorkflow, ...eventNamesNode];
export type EventMessageTypes =