perf(core): Optimize workflow activation errors (#8242)

At https://github.com/n8n-io/n8n/pull/8213 we introduced Redis hashes
for workflow ownership and manual webhooks...

- to remove clutter from multiple related keys at the top level,
- to improve performance by preventing serializing-deserializing, and
- to guarantee atomicity during concurrent updates in multi-main setup.

Workflow activation errors can also benefit from this. Added test
coverage as well.

To test manually, create a workflow with a trigger with an invalid
credential, edit the workflow's `active` column to `true`, and restart.
The activation error should show as a red triangle on canvas and in the
workflow list.
This commit is contained in:
Iván Ovejero
2024-01-05 13:06:42 +01:00
committed by GitHub
parent 23a4ac96c0
commit f2939568cf
3 changed files with 102 additions and 30 deletions

View File

@@ -425,7 +425,7 @@ export class ActiveWorkflowRunner {
void this.activeWorkflows.remove(workflowData.id);
void this.activationErrorsService.set(workflowData.id, error.message);
void this.activationErrorsService.register(workflowData.id, error.message);
// Run Error Workflow if defined
const activationError = new WorkflowActivationError(
@@ -630,13 +630,13 @@ export class ActiveWorkflowRunner {
// Workflow got now successfully activated so make sure nothing is left in the queue
this.removeQueuedWorkflowActivation(workflowId);
await this.activationErrorsService.unset(workflowId);
await this.activationErrorsService.deregister(workflowId);
const triggerCount = this.countTriggers(workflow, additionalData);
await this.workflowRepository.updateWorkflowTriggerCount(workflow.id, triggerCount);
} catch (e) {
const error = e instanceof Error ? e : new Error(`${e}`);
await this.activationErrorsService.set(workflowId, error.message);
await this.activationErrorsService.register(workflowId, error.message);
throw e;
}
@@ -757,7 +757,7 @@ export class ActiveWorkflowRunner {
);
}
await this.activationErrorsService.unset(workflowId);
await this.activationErrorsService.deregister(workflowId);
if (this.queuedActivations[workflowId] !== undefined) {
this.removeQueuedWorkflowActivation(workflowId);
@@ -824,6 +824,6 @@ export class ActiveWorkflowRunner {
}
async removeActivationError(workflowId: string) {
await this.activationErrorsService.unset(workflowId);
await this.activationErrorsService.deregister(workflowId);
}
}