refactor(core): Couple of refactors on WorkflowRunner and ActiveExecutions (no-changelog) (#8487)
This commit is contained in:
committed by
GitHub
parent
dc068ce2e6
commit
c04f92f7fd
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user