refactor(core): Couple of refactors on WorkflowRunner and ActiveExecutions (no-changelog) (#8487)

This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2024-02-06 18:09:50 +01:00
committed by GitHub
parent dc068ce2e6
commit c04f92f7fd
6 changed files with 66 additions and 143 deletions

View File

@@ -6,7 +6,7 @@ import type {
IRun,
ExecutionStatus,
} from 'n8n-workflow';
import { ApplicationError, WorkflowOperationError, createDeferredPromise } from 'n8n-workflow';
import { ApplicationError, createDeferredPromise, sleep } from 'n8n-workflow';
import type {
ExecutionPayload,
@@ -22,7 +22,7 @@ import { Logger } from '@/Logger';
@Service()
export class ActiveExecutions {
private activeExecutions: {
[index: string]: IExecutingWorkflowData;
[executionId: string]: IExecutingWorkflowData;
} = {};
constructor(
@@ -87,32 +87,17 @@ export class ActiveExecutions {
/**
* Attaches an execution
*
*/
attachWorkflowExecution(executionId: string, workflowExecution: PCancelable<IRun>) {
const execution = this.activeExecutions[executionId];
if (execution === undefined) {
throw new ApplicationError('No active execution found to attach to workflow execution to', {
extra: { executionId },
});
}
execution.workflowExecution = workflowExecution;
this.getExecution(executionId).workflowExecution = workflowExecution;
}
attachResponsePromise(
executionId: string,
responsePromise: IDeferredPromise<IExecuteResponsePromiseData>,
): void {
const execution = this.activeExecutions[executionId];
if (execution === undefined) {
throw new ApplicationError('No active execution found to attach to workflow execution to', {
extra: { executionId },
});
}
execution.responsePromise = responsePromise;
this.getExecution(executionId).responsePromise = responsePromise;
}
resolveResponsePromise(executionId: string, response: IExecuteResponsePromiseData): void {
@@ -126,7 +111,6 @@ export class ActiveExecutions {
/**
* Remove an active execution
*
*/
remove(executionId: string, fullRunData?: IRun): void {
const execution = this.activeExecutions[executionId];
@@ -135,7 +119,6 @@ export class ActiveExecutions {
}
// Resolve all the waiting promises
for (const promise of execution.postExecutePromises) {
promise.resolve(fullRunData);
}
@@ -160,28 +143,17 @@ export class ActiveExecutions {
}
/**
* Returns a promise which will resolve with the data of the execution
* with the given id
*
* @param {string} executionId The id of the execution to wait for
* Returns a promise which will resolve with the data of the execution with the given id
*/
async getPostExecutePromise(executionId: string): Promise<IRun | undefined> {
const execution = this.activeExecutions[executionId];
if (execution === undefined) {
throw new WorkflowOperationError(`There is no active execution with id "${executionId}".`);
}
// Create the promise which will be resolved when the execution finished
const waitPromise = await createDeferredPromise<IRun | undefined>();
execution.postExecutePromises.push(waitPromise);
this.getExecution(executionId).postExecutePromises.push(waitPromise);
return await waitPromise.promise();
}
/**
* Returns all the currently active executions
*
*/
getActiveExecutions(): IExecutionsCurrentSummary[] {
const returnData: IExecutionsCurrentSummary[] = [];
@@ -203,20 +175,42 @@ export class ActiveExecutions {
return returnData;
}
async setStatus(executionId: string, status: ExecutionStatus): Promise<void> {
const execution = this.activeExecutions[executionId];
if (execution === undefined) {
this.logger.debug(
`There is no active execution with id "${executionId}", can't update status to ${status}.`,
);
return;
}
execution.status = status;
setStatus(executionId: string, status: ExecutionStatus) {
this.getExecution(executionId).status = status;
}
getStatus(executionId: string): ExecutionStatus {
return this.getExecution(executionId).status;
}
/** Wait for all active executions to finish */
async shutdown(cancelAll = false) {
let executionIds = Object.keys(this.activeExecutions);
if (cancelAll) {
const stopPromises = executionIds.map(
async (executionId) => await this.stopExecution(executionId),
);
await Promise.allSettled(stopPromises);
}
let count = 0;
while (executionIds.length !== 0) {
if (count++ % 4 === 0) {
this.logger.info(`Waiting for ${executionIds.length} active executions to finish...`);
}
await sleep(500);
executionIds = Object.keys(this.activeExecutions);
}
}
private getExecution(executionId: string): IExecutingWorkflowData {
const execution = this.activeExecutions[executionId];
return execution?.status ?? 'unknown';
if (!execution) {
throw new ApplicationError('No active execution found', { extra: { executionId } });
}
return execution;
}
}