Skip to content
2 changes: 1 addition & 1 deletion packages/cli/src/webhooks/test-webhooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ export class TestWebhooks implements IWebhookManager {
runData?: IRunData;
pushRef?: string;
destinationNode?: string;
triggerToStartFrom?: WorkflowRequest.ManualRunPayload['triggerToStartFrom'];
triggerToStartFrom?: WorkflowRequest.FullManualExecutionFromKnownTriggerPayload['triggerToStartFrom'];
}) {
const {
userId,
Expand Down
40 changes: 40 additions & 0 deletions packages/cli/src/workflow-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,46 @@ export class WorkflowRunner {
restartExecutionId?: string,
responsePromise?: IDeferredPromise<IExecuteResponsePromiseData>,
): Promise<string> {
const offloadingManualExecutionsInQueueMode =
this.executionsConfig.mode === 'queue' &&
process.env.OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS === 'true';

/**
* Historically, manual executions in scaling mode ran in the main process,
* so some execution details were never persisted in the database.
*
* Currently, manual executions in scaling mode are offloaded to workers,
* so we persist all details to give workers full access to them.
*/
if (data.executionMode === 'manual' && offloadingManualExecutionsInQueueMode) {
console.log('offloadingManualExecutionsInQueueMode');
data.executionData = createRunExecutionData({
startData: {
startNodes: data.startNodes,
destinationNode: data.destinationNode,
},
resultData: {
pinData: data.pinData,
// If `runData` is initialized to an empty object the execution will
// be treated like a partial manual execution instead of a full
// manual execution.
// So we have to set this to null to instruct
// `createRunExecutionData` to not initialize it.
runData: data.runData ?? null,
},
manualData: {
userId: data.userId,
dirtyNodeNames: data.dirtyNodeNames,
triggerToStartFrom: data.triggerToStartFrom,
},
// If `executionData` is initialized the execution will be treated like
// a resumed execution after waiting, instead of a manual execution.
// So we have to set this to null to instruct `createRunExecutionData`
// to not initialize it.
executionData: null,
});
}

// Register a new execution
const executionId = await this.activeExecutions.add(data, restartExecutionId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -415,61 +415,61 @@ describe('WorkflowExecutionService', () => {
});

it('should return `null` if no pindata', () => {
const node = workflowExecutionService.selectPinnedActivatorStarter(workflow, []);
const node = workflowExecutionService.selectPinnedTrigger(workflow, []);

expect(node).toBeNull();
});

it('should return `null` if no starter nodes', () => {
const node = workflowExecutionService.selectPinnedActivatorStarter(workflow);
const node = workflowExecutionService.selectPinnedTrigger(workflow);

expect(node).toBeNull();
});

it('should select webhook node if only choice', () => {
workflow.nodes.push(webhookNode);

const node = workflowExecutionService.selectPinnedActivatorStarter(workflow, [], pinData);
const node = workflowExecutionService.selectPinnedTrigger(workflow, [], pinData);

expect(node).toEqual(webhookNode);
});

it('should return `null` if no choice', () => {
workflow.nodes.push(hackerNewsNode);

const node = workflowExecutionService.selectPinnedActivatorStarter(workflow, [], pinData);
const node = workflowExecutionService.selectPinnedTrigger(workflow, [], pinData);

expect(node).toBeNull();
});

it('should return ignore Respond to Webhook', () => {
workflow.nodes.push(respondToWebhookNode);

const node = workflowExecutionService.selectPinnedActivatorStarter(workflow, [], pinData);
const node = workflowExecutionService.selectPinnedTrigger(workflow, [], pinData);

expect(node).toBeNull();
});

it('should select execute workflow trigger if only choice', () => {
workflow.nodes.push(executeWorkflowTriggerNode);

const node = workflowExecutionService.selectPinnedActivatorStarter(workflow, [], pinData);
const node = workflowExecutionService.selectPinnedTrigger(workflow, [], pinData);

expect(node).toEqual(executeWorkflowTriggerNode);
});

it('should favor webhook node over execute workflow trigger', () => {
workflow.nodes.push(webhookNode, executeWorkflowTriggerNode);

const node = workflowExecutionService.selectPinnedActivatorStarter(workflow, [], pinData);
const node = workflowExecutionService.selectPinnedTrigger(workflow, [], pinData);

expect(node).toEqual(webhookNode);
});

it('should favor first webhook node over second webhook node', () => {
workflow.nodes.push(webhookNode, secondWebhookNode);

const node = workflowExecutionService.selectPinnedActivatorStarter(workflow, [], pinData);
const node = workflowExecutionService.selectPinnedTrigger(workflow, [], pinData);

expect(node).toEqual(webhookNode);
});
Expand All @@ -481,7 +481,7 @@ describe('WorkflowExecutionService', () => {
...createMainConnection(secondWebhookNode.name, secondHackerNewsNode.name),
};

const node = workflowExecutionService.selectPinnedActivatorStarter(
const node = workflowExecutionService.selectPinnedTrigger(
workflow,
[],
{ ...pinData, [secondWebhookNode.name]: [{ json: { key: 'value' } }] },
Expand Down
Loading
Loading