mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-07-02 11:12:20 +08:00
Merge branch 'next' into develop
This commit is contained in:
commit
7093f478c1
@ -168,6 +168,18 @@ const workflowFieldset = {
|
||||
multiple: true,
|
||||
},
|
||||
},
|
||||
stackLimit: {
|
||||
type: 'number',
|
||||
title: `{{ t("Maximum number of loop calls", { ns: "${NAMESPACE}" }) }}`,
|
||||
description: `{{ t("If the number of loop calls is too large, there will be performance issues.", { ns: "${NAMESPACE}" }) }}`,
|
||||
'x-decorator': 'FormItem',
|
||||
default: 1,
|
||||
'x-component': 'InputNumber',
|
||||
'x-component-props': {
|
||||
min: 1,
|
||||
precision: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -94,5 +94,7 @@
|
||||
"Trigger in executed workflow cannot be modified": "Trigger in executed workflow cannot be modified",
|
||||
"Node in executed workflow cannot be modified": "Node in executed workflow cannot be modified",
|
||||
"Can not delete": "Can not delete",
|
||||
"The result of this node has been referenced by other nodes ({{nodes}}), please remove the usage before deleting.": "The result of this node has been referenced by other nodes ({{nodes}}), please remove the usage before deleting."
|
||||
"The result of this node has been referenced by other nodes ({{nodes}}), please remove the usage before deleting.": "The result of this node has been referenced by other nodes ({{nodes}}), please remove the usage before deleting.",
|
||||
"Maximum number of loop calls": "Maximum number of loop calls",
|
||||
"If the number of loop calls is too large, there will be performance issues.": "If the number of loop calls is too large, there will be performance issues."
|
||||
}
|
||||
|
@ -31,6 +31,8 @@
|
||||
"Data operation nodes in workflow will run in a same transaction until any interruption. Any failure will cause data rollback, and will also rollback the history of the execution.":
|
||||
"工作流中的节点将在同一个事务中运行。任何失败都会导致数据回滚,同时也会回滚相应的执行历史。",
|
||||
"Auto delete history when execution is on end status": "执行结束后自动删除对应状态的历史记录",
|
||||
"Maximum number of loop calls": "最大循环调用次数",
|
||||
"If the number of loop calls is too large, there will be performance issues.": "如果循环调用次数过大,会有性能问题",
|
||||
"Trigger": "触发器",
|
||||
"Unknown trigger": "未知触发器",
|
||||
"Workflow with unknown type will cause error. Please delete it or check plugin which provide this type.": "未知类型的工作流会导致错误,请删除或检查提供该类型的插件。",
|
||||
|
@ -488,9 +488,10 @@ export default class PluginWorkflowServer extends Plugin {
|
||||
transaction: options.transaction,
|
||||
});
|
||||
|
||||
if (existed) {
|
||||
const limitCount = workflow.options.stackLimit || 1;
|
||||
if (existed >= limitCount) {
|
||||
this.getLogger(workflow.id).warn(
|
||||
`workflow ${workflow.id} has already been triggered in stacks executions (${stack}), and newly triggering will be skipped.`,
|
||||
`workflow ${workflow.id} has already been triggered in stacks executions (${stack}), and max call coont is ${limitCount}, newly triggering will be skipped.`,
|
||||
);
|
||||
|
||||
valid = false;
|
||||
|
@ -841,6 +841,128 @@ describe('workflow > triggers > collection', () => {
|
||||
expect(e2s.length).toBe(1);
|
||||
expect(e2s[0].status).toBe(EXECUTION_STATUS.RESOLVED);
|
||||
});
|
||||
|
||||
it('stack limit for same execution', async () => {
|
||||
const workflow = await WorkflowModel.create({
|
||||
enabled: true,
|
||||
type: 'collection',
|
||||
config: {
|
||||
mode: 1,
|
||||
collection: 'posts',
|
||||
},
|
||||
options: {
|
||||
stackLimit: 3,
|
||||
},
|
||||
});
|
||||
|
||||
const n1 = await workflow.createNode({
|
||||
type: 'create',
|
||||
config: {
|
||||
collection: 'posts',
|
||||
params: {
|
||||
values: {
|
||||
title: 't2',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const p1 = await PostRepo.create({ values: { title: 't1' } });
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const posts = await PostRepo.find();
|
||||
expect(posts.length).toBe(4);
|
||||
|
||||
const e1s = await workflow.getExecutions();
|
||||
expect(e1s.length).toBe(3);
|
||||
expect(e1s[0].status).toBe(EXECUTION_STATUS.RESOLVED);
|
||||
expect(e1s[1].status).toBe(EXECUTION_STATUS.RESOLVED);
|
||||
expect(e1s[2].status).toBe(EXECUTION_STATUS.RESOLVED);
|
||||
|
||||
// NOTE: second trigger to ensure no skipped event
|
||||
const p3 = await PostRepo.create({ values: { title: 't3' } });
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const posts2 = await PostRepo.find();
|
||||
expect(posts2.length).toBe(8);
|
||||
|
||||
const e2s = await workflow.getExecutions({ order: [['createdAt', 'DESC']] });
|
||||
expect(e2s.length).toBe(6);
|
||||
expect(e2s[3].status).toBe(EXECUTION_STATUS.RESOLVED);
|
||||
expect(e2s[4].status).toBe(EXECUTION_STATUS.RESOLVED);
|
||||
expect(e2s[5].status).toBe(EXECUTION_STATUS.RESOLVED);
|
||||
});
|
||||
|
||||
it('stack limit for multiple cycling trigger', async () => {
|
||||
const w1 = await WorkflowModel.create({
|
||||
enabled: true,
|
||||
type: 'collection',
|
||||
config: {
|
||||
mode: 1,
|
||||
collection: 'posts',
|
||||
},
|
||||
options: {
|
||||
stackLimit: 3,
|
||||
},
|
||||
});
|
||||
|
||||
const n1 = await w1.createNode({
|
||||
type: 'create',
|
||||
config: {
|
||||
collection: 'categories',
|
||||
params: {
|
||||
values: {
|
||||
title: 'c1',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const w2 = await WorkflowModel.create({
|
||||
enabled: true,
|
||||
type: 'collection',
|
||||
config: {
|
||||
mode: 1,
|
||||
collection: 'categories',
|
||||
},
|
||||
options: {
|
||||
stackLimit: 3,
|
||||
},
|
||||
});
|
||||
|
||||
const n2 = await w2.createNode({
|
||||
type: 'create',
|
||||
config: {
|
||||
collection: 'posts',
|
||||
params: {
|
||||
values: {
|
||||
title: 't2',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const p1 = await PostRepo.create({ values: { title: 't1' } });
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const posts = await PostRepo.find();
|
||||
expect(posts.length).toBe(4);
|
||||
|
||||
const e1s = await w1.getExecutions();
|
||||
expect(e1s.length).toBe(3);
|
||||
expect(e1s[0].status).toBe(EXECUTION_STATUS.RESOLVED);
|
||||
expect(e1s[1].status).toBe(EXECUTION_STATUS.RESOLVED);
|
||||
expect(e1s[2].status).toBe(EXECUTION_STATUS.RESOLVED);
|
||||
|
||||
const e2s = await w2.getExecutions();
|
||||
expect(e2s.length).toBe(3);
|
||||
expect(e2s[0].status).toBe(EXECUTION_STATUS.RESOLVED);
|
||||
expect(e2s[1].status).toBe(EXECUTION_STATUS.RESOLVED);
|
||||
expect(e2s[2].status).toBe(EXECUTION_STATUS.RESOLVED);
|
||||
});
|
||||
});
|
||||
|
||||
describe('sync', () => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user