perf(core): Batch items sent in runonceforeachitem mode (no-changelog) (#11870)

Co-authored-by: Iván Ovejero <ivov.src@gmail.com>
This commit is contained in:
Tomi Turtiainen
2024-11-26 12:21:51 +02:00
committed by GitHub
parent 1adb730599
commit e22d0f3877
17 changed files with 457 additions and 83 deletions

View File

@@ -18,6 +18,7 @@ export class JsTaskRunnerSandbox {
private readonly nodeMode: CodeExecutionMode,
private readonly workflowMode: WorkflowExecuteMode,
private readonly executeFunctions: IExecuteFunctions,
private readonly chunkSize = 1000,
) {}
async runCodeAllItems(): Promise<INodeExecutionData[]> {
@@ -39,24 +40,37 @@ export class JsTaskRunnerSandbox {
: this.throwExecutionError(executionResult.error);
}
async runCodeForEachItem(): Promise<INodeExecutionData[]> {
async runCodeForEachItem(numInputItems: number): Promise<INodeExecutionData[]> {
validateNoDisallowedMethodsInRunForEach(this.jsCode, 0);
const itemIndex = 0;
const chunks = this.chunkInputItems(numInputItems);
let executionResults: INodeExecutionData[] = [];
const executionResult = await this.executeFunctions.startJob<INodeExecutionData[]>(
'javascript',
{
code: this.jsCode,
nodeMode: this.nodeMode,
workflowMode: this.workflowMode,
continueOnFail: this.executeFunctions.continueOnFail(),
},
itemIndex,
);
for (const chunk of chunks) {
const executionResult = await this.executeFunctions.startJob<INodeExecutionData[]>(
'javascript',
{
code: this.jsCode,
nodeMode: this.nodeMode,
workflowMode: this.workflowMode,
continueOnFail: this.executeFunctions.continueOnFail(),
chunk: {
startIndex: chunk.startIdx,
count: chunk.count,
},
},
itemIndex,
);
return executionResult.ok
? executionResult.result
: this.throwExecutionError(executionResult.error);
if (!executionResult.ok) {
return this.throwExecutionError(executionResult.error);
}
executionResults = executionResults.concat(executionResult.result);
}
return executionResults;
}
private throwExecutionError(error: unknown): never {
@@ -70,4 +84,22 @@ export class JsTaskRunnerSandbox {
throw new ApplicationError(`Unknown error: ${JSON.stringify(error)}`);
}
/** Chunks the input items into chunks of 1000 items each */
private chunkInputItems(numInputItems: number) {
const numChunks = Math.ceil(numInputItems / this.chunkSize);
const chunks = [];
for (let i = 0; i < numChunks; i++) {
const startIdx = i * this.chunkSize;
const isLastChunk = i === numChunks - 1;
const count = isLastChunk ? numInputItems - startIdx : this.chunkSize;
chunks.push({
startIdx,
count,
});
}
return chunks;
}
}