tachybase_todo/packages/plugins/workflow/src/server/instructions/parallel.ts

117 lines
3.7 KiB
TypeScript
Raw Normal View History

import FlowNodeModel from "../models/FlowNode";
import JobModel from "../models/Job";
import Processor from "../Processor";
import { JOB_STATUS } from "../constants";
export const PARALLEL_MODE = {
ALL: 'all',
ANY: 'any',
RACE: 'race'
} as const;
const Modes = {
[PARALLEL_MODE.ALL]: {
next(previous) {
Feat(plugin-workflow) manual instruction (#1339) * feat(plugin-workflow): add prompt node * feat(plugin-workflow): useValueGetter for all instructions and triggers * feat(plugin-workflow): add workflow block initializer * refactor(plugin-workflow): change prompt node type to manual * feat(plugin-workflow): add ModeConfig component for mode * feat(plugin-workflow): add todo drawer * feat(plugin-workflow): add block value provider * feat(plugin-workflow): improve todo block and drawer * fix(plugin-workflow): fix instruction name in test cases * fix(plugin-workflow): fix test cases * refactor(plugin-workflow): change param type of collection field initializer * feat(plugin-workflow): add filter types for getters * fix(plugin-workflow): fix assignees variable * fix(plugin-workflow): filter todo by exist workflow * fix(plugin-workflow): fix duplicated save action in manual config * fix(plugin-workflow): fix transaction * feat(plugin-workflow): destroy workflow will be cascaded * fix(plugin-workflow): fix merge * fix(plugin-workflow): fix locale * fix(plugin-workflow): allow open ui view when executed * fix(plugin-workflow): change todo table filter * feat(plugin-workflow): use formula for calculation * fix(plugin-workflow): fix variable template regexp * fix(plugin-workflow): fix sub-options logic with types * refactor(plugin-workflow): drop useless component * fix(plugin-workflow): fix manual node action button * feat(plugin-workflow): add new variable input component * refactor(plugin-workflow): change all variable to new component * fix(plugin-workflow): fix type * fix(plugin-workflow): fix functions init * fix(plugin-workflow): change jsonb to json for stable order * fix(plugin-workflow): fix duplicated field name when initialize * fix(plugin-workflow): fix manual result in manual block * test(plugin-workflow): log field initializer props * fix(plugin-workflow): fix nullable arguments * test(plugin-workflow): test initializer fields schema * fix: observer * fix(plugin-workflow): adjust hints * fix(plugin-workflow): fix locale and cursor in variable input * refactor(plugin-workflow): change status keys * fix(plugin-workflow): fix parallel instruction * fix(plugin-workflow): fix calculation migration * fix(plugin-workflow): move tasks native filter to server * fix(plugin-workflow): fix manual options for variable * fix(plugin-workflow): fix conflict * fix(plugin-workflow): fix some bugs * fix(plugin-workflow): fix todo list filter and locale * fix(plugin-workflow): fix update action of workflow * refactor(plugin-workflow): add legacy condition calculation as basic engine * fix(plugin-workflow): fix type * fix(plugin-workflow): fix condition basic calculation * fix(plugin-workflow): fix type * fix(plugin-workflow): fix migration * fix(plugin-workflow): fix evaluators and scope * fix(plugin-workflow): remove disabled type select in schema config * fix(plugin-workflow): fix manual form schema designer --------- Co-authored-by: chenos <chenlinxh@gmail.com>
2023-02-20 11:52:06 +08:00
return previous.status >= JOB_STATUS.PENDING;
},
getStatus(result) {
Feat(plugin-workflow) manual instruction (#1339) * feat(plugin-workflow): add prompt node * feat(plugin-workflow): useValueGetter for all instructions and triggers * feat(plugin-workflow): add workflow block initializer * refactor(plugin-workflow): change prompt node type to manual * feat(plugin-workflow): add ModeConfig component for mode * feat(plugin-workflow): add todo drawer * feat(plugin-workflow): add block value provider * feat(plugin-workflow): improve todo block and drawer * fix(plugin-workflow): fix instruction name in test cases * fix(plugin-workflow): fix test cases * refactor(plugin-workflow): change param type of collection field initializer * feat(plugin-workflow): add filter types for getters * fix(plugin-workflow): fix assignees variable * fix(plugin-workflow): filter todo by exist workflow * fix(plugin-workflow): fix duplicated save action in manual config * fix(plugin-workflow): fix transaction * feat(plugin-workflow): destroy workflow will be cascaded * fix(plugin-workflow): fix merge * fix(plugin-workflow): fix locale * fix(plugin-workflow): allow open ui view when executed * fix(plugin-workflow): change todo table filter * feat(plugin-workflow): use formula for calculation * fix(plugin-workflow): fix variable template regexp * fix(plugin-workflow): fix sub-options logic with types * refactor(plugin-workflow): drop useless component * fix(plugin-workflow): fix manual node action button * feat(plugin-workflow): add new variable input component * refactor(plugin-workflow): change all variable to new component * fix(plugin-workflow): fix type * fix(plugin-workflow): fix functions init * fix(plugin-workflow): change jsonb to json for stable order * fix(plugin-workflow): fix duplicated field name when initialize * fix(plugin-workflow): fix manual result in manual block * test(plugin-workflow): log field initializer props * fix(plugin-workflow): fix nullable arguments * test(plugin-workflow): test initializer fields schema * fix: observer * fix(plugin-workflow): adjust hints * fix(plugin-workflow): fix locale and cursor in variable input * refactor(plugin-workflow): change status keys * fix(plugin-workflow): fix parallel instruction * fix(plugin-workflow): fix calculation migration * fix(plugin-workflow): move tasks native filter to server * fix(plugin-workflow): fix manual options for variable * fix(plugin-workflow): fix conflict * fix(plugin-workflow): fix some bugs * fix(plugin-workflow): fix todo list filter and locale * fix(plugin-workflow): fix update action of workflow * refactor(plugin-workflow): add legacy condition calculation as basic engine * fix(plugin-workflow): fix type * fix(plugin-workflow): fix condition basic calculation * fix(plugin-workflow): fix type * fix(plugin-workflow): fix migration * fix(plugin-workflow): fix evaluators and scope * fix(plugin-workflow): remove disabled type select in schema config * fix(plugin-workflow): fix manual form schema designer --------- Co-authored-by: chenos <chenlinxh@gmail.com>
2023-02-20 11:52:06 +08:00
const failedStatus = result.find(status => status != null && status < JOB_STATUS.PENDING)
if (typeof failedStatus !== 'undefined') {
return failedStatus;
}
if (result.every(status => status != null && status === JOB_STATUS.RESOLVED)) {
return JOB_STATUS.RESOLVED;
}
return JOB_STATUS.PENDING;
}
},
[PARALLEL_MODE.ANY]: {
next(previous) {
Feat(plugin-workflow) manual instruction (#1339) * feat(plugin-workflow): add prompt node * feat(plugin-workflow): useValueGetter for all instructions and triggers * feat(plugin-workflow): add workflow block initializer * refactor(plugin-workflow): change prompt node type to manual * feat(plugin-workflow): add ModeConfig component for mode * feat(plugin-workflow): add todo drawer * feat(plugin-workflow): add block value provider * feat(plugin-workflow): improve todo block and drawer * fix(plugin-workflow): fix instruction name in test cases * fix(plugin-workflow): fix test cases * refactor(plugin-workflow): change param type of collection field initializer * feat(plugin-workflow): add filter types for getters * fix(plugin-workflow): fix assignees variable * fix(plugin-workflow): filter todo by exist workflow * fix(plugin-workflow): fix duplicated save action in manual config * fix(plugin-workflow): fix transaction * feat(plugin-workflow): destroy workflow will be cascaded * fix(plugin-workflow): fix merge * fix(plugin-workflow): fix locale * fix(plugin-workflow): allow open ui view when executed * fix(plugin-workflow): change todo table filter * feat(plugin-workflow): use formula for calculation * fix(plugin-workflow): fix variable template regexp * fix(plugin-workflow): fix sub-options logic with types * refactor(plugin-workflow): drop useless component * fix(plugin-workflow): fix manual node action button * feat(plugin-workflow): add new variable input component * refactor(plugin-workflow): change all variable to new component * fix(plugin-workflow): fix type * fix(plugin-workflow): fix functions init * fix(plugin-workflow): change jsonb to json for stable order * fix(plugin-workflow): fix duplicated field name when initialize * fix(plugin-workflow): fix manual result in manual block * test(plugin-workflow): log field initializer props * fix(plugin-workflow): fix nullable arguments * test(plugin-workflow): test initializer fields schema * fix: observer * fix(plugin-workflow): adjust hints * fix(plugin-workflow): fix locale and cursor in variable input * refactor(plugin-workflow): change status keys * fix(plugin-workflow): fix parallel instruction * fix(plugin-workflow): fix calculation migration * fix(plugin-workflow): move tasks native filter to server * fix(plugin-workflow): fix manual options for variable * fix(plugin-workflow): fix conflict * fix(plugin-workflow): fix some bugs * fix(plugin-workflow): fix todo list filter and locale * fix(plugin-workflow): fix update action of workflow * refactor(plugin-workflow): add legacy condition calculation as basic engine * fix(plugin-workflow): fix type * fix(plugin-workflow): fix condition basic calculation * fix(plugin-workflow): fix type * fix(plugin-workflow): fix migration * fix(plugin-workflow): fix evaluators and scope * fix(plugin-workflow): remove disabled type select in schema config * fix(plugin-workflow): fix manual form schema designer --------- Co-authored-by: chenos <chenlinxh@gmail.com>
2023-02-20 11:52:06 +08:00
return previous.status <= JOB_STATUS.PENDING;
},
getStatus(result) {
if (result.some(status => status != null && status === JOB_STATUS.RESOLVED)) {
return JOB_STATUS.RESOLVED;
}
if (result.some(status => status != null ? status === JOB_STATUS.PENDING : true)) {
return JOB_STATUS.PENDING;
}
Feat(plugin-workflow) manual instruction (#1339) * feat(plugin-workflow): add prompt node * feat(plugin-workflow): useValueGetter for all instructions and triggers * feat(plugin-workflow): add workflow block initializer * refactor(plugin-workflow): change prompt node type to manual * feat(plugin-workflow): add ModeConfig component for mode * feat(plugin-workflow): add todo drawer * feat(plugin-workflow): add block value provider * feat(plugin-workflow): improve todo block and drawer * fix(plugin-workflow): fix instruction name in test cases * fix(plugin-workflow): fix test cases * refactor(plugin-workflow): change param type of collection field initializer * feat(plugin-workflow): add filter types for getters * fix(plugin-workflow): fix assignees variable * fix(plugin-workflow): filter todo by exist workflow * fix(plugin-workflow): fix duplicated save action in manual config * fix(plugin-workflow): fix transaction * feat(plugin-workflow): destroy workflow will be cascaded * fix(plugin-workflow): fix merge * fix(plugin-workflow): fix locale * fix(plugin-workflow): allow open ui view when executed * fix(plugin-workflow): change todo table filter * feat(plugin-workflow): use formula for calculation * fix(plugin-workflow): fix variable template regexp * fix(plugin-workflow): fix sub-options logic with types * refactor(plugin-workflow): drop useless component * fix(plugin-workflow): fix manual node action button * feat(plugin-workflow): add new variable input component * refactor(plugin-workflow): change all variable to new component * fix(plugin-workflow): fix type * fix(plugin-workflow): fix functions init * fix(plugin-workflow): change jsonb to json for stable order * fix(plugin-workflow): fix duplicated field name when initialize * fix(plugin-workflow): fix manual result in manual block * test(plugin-workflow): log field initializer props * fix(plugin-workflow): fix nullable arguments * test(plugin-workflow): test initializer fields schema * fix: observer * fix(plugin-workflow): adjust hints * fix(plugin-workflow): fix locale and cursor in variable input * refactor(plugin-workflow): change status keys * fix(plugin-workflow): fix parallel instruction * fix(plugin-workflow): fix calculation migration * fix(plugin-workflow): move tasks native filter to server * fix(plugin-workflow): fix manual options for variable * fix(plugin-workflow): fix conflict * fix(plugin-workflow): fix some bugs * fix(plugin-workflow): fix todo list filter and locale * fix(plugin-workflow): fix update action of workflow * refactor(plugin-workflow): add legacy condition calculation as basic engine * fix(plugin-workflow): fix type * fix(plugin-workflow): fix condition basic calculation * fix(plugin-workflow): fix type * fix(plugin-workflow): fix migration * fix(plugin-workflow): fix evaluators and scope * fix(plugin-workflow): remove disabled type select in schema config * fix(plugin-workflow): fix manual form schema designer --------- Co-authored-by: chenos <chenlinxh@gmail.com>
2023-02-20 11:52:06 +08:00
return JOB_STATUS.FAILED;
}
},
[PARALLEL_MODE.RACE]: {
next(previous) {
return previous.status === JOB_STATUS.PENDING;
},
getStatus(result) {
if (result.some(status => status != null && status === JOB_STATUS.RESOLVED)) {
return JOB_STATUS.RESOLVED;
}
Feat(plugin-workflow) manual instruction (#1339) * feat(plugin-workflow): add prompt node * feat(plugin-workflow): useValueGetter for all instructions and triggers * feat(plugin-workflow): add workflow block initializer * refactor(plugin-workflow): change prompt node type to manual * feat(plugin-workflow): add ModeConfig component for mode * feat(plugin-workflow): add todo drawer * feat(plugin-workflow): add block value provider * feat(plugin-workflow): improve todo block and drawer * fix(plugin-workflow): fix instruction name in test cases * fix(plugin-workflow): fix test cases * refactor(plugin-workflow): change param type of collection field initializer * feat(plugin-workflow): add filter types for getters * fix(plugin-workflow): fix assignees variable * fix(plugin-workflow): filter todo by exist workflow * fix(plugin-workflow): fix duplicated save action in manual config * fix(plugin-workflow): fix transaction * feat(plugin-workflow): destroy workflow will be cascaded * fix(plugin-workflow): fix merge * fix(plugin-workflow): fix locale * fix(plugin-workflow): allow open ui view when executed * fix(plugin-workflow): change todo table filter * feat(plugin-workflow): use formula for calculation * fix(plugin-workflow): fix variable template regexp * fix(plugin-workflow): fix sub-options logic with types * refactor(plugin-workflow): drop useless component * fix(plugin-workflow): fix manual node action button * feat(plugin-workflow): add new variable input component * refactor(plugin-workflow): change all variable to new component * fix(plugin-workflow): fix type * fix(plugin-workflow): fix functions init * fix(plugin-workflow): change jsonb to json for stable order * fix(plugin-workflow): fix duplicated field name when initialize * fix(plugin-workflow): fix manual result in manual block * test(plugin-workflow): log field initializer props * fix(plugin-workflow): fix nullable arguments * test(plugin-workflow): test initializer fields schema * fix: observer * fix(plugin-workflow): adjust hints * fix(plugin-workflow): fix locale and cursor in variable input * refactor(plugin-workflow): change status keys * fix(plugin-workflow): fix parallel instruction * fix(plugin-workflow): fix calculation migration * fix(plugin-workflow): move tasks native filter to server * fix(plugin-workflow): fix manual options for variable * fix(plugin-workflow): fix conflict * fix(plugin-workflow): fix some bugs * fix(plugin-workflow): fix todo list filter and locale * fix(plugin-workflow): fix update action of workflow * refactor(plugin-workflow): add legacy condition calculation as basic engine * fix(plugin-workflow): fix type * fix(plugin-workflow): fix condition basic calculation * fix(plugin-workflow): fix type * fix(plugin-workflow): fix migration * fix(plugin-workflow): fix evaluators and scope * fix(plugin-workflow): remove disabled type select in schema config * fix(plugin-workflow): fix manual form schema designer --------- Co-authored-by: chenos <chenlinxh@gmail.com>
2023-02-20 11:52:06 +08:00
const failedStatus = result.find(status => status != null && status < JOB_STATUS.PENDING);
if (typeof failedStatus !== 'undefined') {
return failedStatus;
}
return JOB_STATUS.PENDING;
}
}
};
export default {
async run(node: FlowNodeModel, prevJob: JobModel, processor: Processor) {
const branches = processor.getBranches(node);
const job = await processor.saveJob({
status: JOB_STATUS.PENDING,
result: Array(branches.length).fill(null),
nodeId: node.id,
upstreamId: prevJob?.id ?? null
});
// NOTE:
// use `reduce` but not `Promise.all` here to avoid racing manupulating db.
// for users, this is almost equivalent to `Promise.all`,
// because of the delay is not significant sensible.
// another benifit of this is, it could handle sequenced branches in future.
const { mode = PARALLEL_MODE.ALL } = node.config;
await branches.reduce((promise: Promise<any>, branch, i) =>
promise.then((previous) => {
if (i && !Modes[mode].next(previous)) {
return Promise.resolve(previous);
}
return processor.run(branch, job);
}), Promise.resolve());
return processor.end(node, job);
},
async resume(node: FlowNodeModel, branchJob, processor: Processor) {
Feat(plugin-workflow) manual instruction (#1339) * feat(plugin-workflow): add prompt node * feat(plugin-workflow): useValueGetter for all instructions and triggers * feat(plugin-workflow): add workflow block initializer * refactor(plugin-workflow): change prompt node type to manual * feat(plugin-workflow): add ModeConfig component for mode * feat(plugin-workflow): add todo drawer * feat(plugin-workflow): add block value provider * feat(plugin-workflow): improve todo block and drawer * fix(plugin-workflow): fix instruction name in test cases * fix(plugin-workflow): fix test cases * refactor(plugin-workflow): change param type of collection field initializer * feat(plugin-workflow): add filter types for getters * fix(plugin-workflow): fix assignees variable * fix(plugin-workflow): filter todo by exist workflow * fix(plugin-workflow): fix duplicated save action in manual config * fix(plugin-workflow): fix transaction * feat(plugin-workflow): destroy workflow will be cascaded * fix(plugin-workflow): fix merge * fix(plugin-workflow): fix locale * fix(plugin-workflow): allow open ui view when executed * fix(plugin-workflow): change todo table filter * feat(plugin-workflow): use formula for calculation * fix(plugin-workflow): fix variable template regexp * fix(plugin-workflow): fix sub-options logic with types * refactor(plugin-workflow): drop useless component * fix(plugin-workflow): fix manual node action button * feat(plugin-workflow): add new variable input component * refactor(plugin-workflow): change all variable to new component * fix(plugin-workflow): fix type * fix(plugin-workflow): fix functions init * fix(plugin-workflow): change jsonb to json for stable order * fix(plugin-workflow): fix duplicated field name when initialize * fix(plugin-workflow): fix manual result in manual block * test(plugin-workflow): log field initializer props * fix(plugin-workflow): fix nullable arguments * test(plugin-workflow): test initializer fields schema * fix: observer * fix(plugin-workflow): adjust hints * fix(plugin-workflow): fix locale and cursor in variable input * refactor(plugin-workflow): change status keys * fix(plugin-workflow): fix parallel instruction * fix(plugin-workflow): fix calculation migration * fix(plugin-workflow): move tasks native filter to server * fix(plugin-workflow): fix manual options for variable * fix(plugin-workflow): fix conflict * fix(plugin-workflow): fix some bugs * fix(plugin-workflow): fix todo list filter and locale * fix(plugin-workflow): fix update action of workflow * refactor(plugin-workflow): add legacy condition calculation as basic engine * fix(plugin-workflow): fix type * fix(plugin-workflow): fix condition basic calculation * fix(plugin-workflow): fix type * fix(plugin-workflow): fix migration * fix(plugin-workflow): fix evaluators and scope * fix(plugin-workflow): remove disabled type select in schema config * fix(plugin-workflow): fix manual form schema designer --------- Co-authored-by: chenos <chenlinxh@gmail.com>
2023-02-20 11:52:06 +08:00
const job = processor.findBranchParentJob(branchJob, node) as JobModel;
const { result, status } = job;
// if parallel has been done (resolved / rejected), do not care newly executed branch jobs.
if (status !== JOB_STATUS.PENDING) {
return null;
}
// find the index of the node which start the branch
Feat(plugin-workflow) manual instruction (#1339) * feat(plugin-workflow): add prompt node * feat(plugin-workflow): useValueGetter for all instructions and triggers * feat(plugin-workflow): add workflow block initializer * refactor(plugin-workflow): change prompt node type to manual * feat(plugin-workflow): add ModeConfig component for mode * feat(plugin-workflow): add todo drawer * feat(plugin-workflow): add block value provider * feat(plugin-workflow): improve todo block and drawer * fix(plugin-workflow): fix instruction name in test cases * fix(plugin-workflow): fix test cases * refactor(plugin-workflow): change param type of collection field initializer * feat(plugin-workflow): add filter types for getters * fix(plugin-workflow): fix assignees variable * fix(plugin-workflow): filter todo by exist workflow * fix(plugin-workflow): fix duplicated save action in manual config * fix(plugin-workflow): fix transaction * feat(plugin-workflow): destroy workflow will be cascaded * fix(plugin-workflow): fix merge * fix(plugin-workflow): fix locale * fix(plugin-workflow): allow open ui view when executed * fix(plugin-workflow): change todo table filter * feat(plugin-workflow): use formula for calculation * fix(plugin-workflow): fix variable template regexp * fix(plugin-workflow): fix sub-options logic with types * refactor(plugin-workflow): drop useless component * fix(plugin-workflow): fix manual node action button * feat(plugin-workflow): add new variable input component * refactor(plugin-workflow): change all variable to new component * fix(plugin-workflow): fix type * fix(plugin-workflow): fix functions init * fix(plugin-workflow): change jsonb to json for stable order * fix(plugin-workflow): fix duplicated field name when initialize * fix(plugin-workflow): fix manual result in manual block * test(plugin-workflow): log field initializer props * fix(plugin-workflow): fix nullable arguments * test(plugin-workflow): test initializer fields schema * fix: observer * fix(plugin-workflow): adjust hints * fix(plugin-workflow): fix locale and cursor in variable input * refactor(plugin-workflow): change status keys * fix(plugin-workflow): fix parallel instruction * fix(plugin-workflow): fix calculation migration * fix(plugin-workflow): move tasks native filter to server * fix(plugin-workflow): fix manual options for variable * fix(plugin-workflow): fix conflict * fix(plugin-workflow): fix some bugs * fix(plugin-workflow): fix todo list filter and locale * fix(plugin-workflow): fix update action of workflow * refactor(plugin-workflow): add legacy condition calculation as basic engine * fix(plugin-workflow): fix type * fix(plugin-workflow): fix condition basic calculation * fix(plugin-workflow): fix type * fix(plugin-workflow): fix migration * fix(plugin-workflow): fix evaluators and scope * fix(plugin-workflow): remove disabled type select in schema config * fix(plugin-workflow): fix manual form schema designer --------- Co-authored-by: chenos <chenlinxh@gmail.com>
2023-02-20 11:52:06 +08:00
const jobNode = processor.nodesMap.get(branchJob.nodeId) as FlowNodeModel;
const branchStartNode = processor.findBranchStartNode(jobNode, node) as FlowNodeModel;
const branches = processor.getBranches(node);
const branchIndex = branches.indexOf(branchStartNode);
const { mode = PARALLEL_MODE.ALL } = node.config || {};
const newResult = [...result.slice(0, branchIndex), branchJob.status, ...result.slice(branchIndex + 1)];
job.set({
result: newResult,
status: Modes[mode].getStatus(newResult)
});
if (job.status === JOB_STATUS.PENDING) {
await job.save({ transaction: processor.transaction });
return processor.end(node, job);
}
return job;
}
};