From 5627a4bfde047d03e62815611eadf4facfb14f25 Mon Sep 17 00:00:00 2001 From: heheer Date: Wed, 21 Aug 2024 20:23:35 +0800 Subject: [PATCH] feat: add http node timeout (#2465) * fix $ in replacement string misinterpreted as regex special character * add http timeout * delete console log --- packages/global/core/workflow/constants.ts | 1 + .../core/workflow/template/system/http468.ts | 10 +++ .../core/workflow/dispatch/tools/http468.ts | 12 ++-- packages/web/i18n/en/common.json | 4 +- packages/web/i18n/zh/common.json | 6 +- .../Flow/NodeTemplatesModal.tsx | 1 - .../Flow/nodes/NodeHttp/index.tsx | 66 ++++++++++++++++++- 7 files changed, 90 insertions(+), 10 deletions(-) diff --git a/packages/global/core/workflow/constants.ts b/packages/global/core/workflow/constants.ts index e343d4d93..fc34a73ab 100644 --- a/packages/global/core/workflow/constants.ts +++ b/packages/global/core/workflow/constants.ts @@ -105,6 +105,7 @@ export enum NodeInputKeyEnum { httpMethod = 'system_httpMethod', httpParams = 'system_httpParams', httpJsonBody = 'system_httpJsonBody', + httpTimeout = 'system_httpTimeout', abandon_httpUrl = 'url', // app diff --git a/packages/global/core/workflow/template/system/http468.ts b/packages/global/core/workflow/template/system/http468.ts index c7846f786..ebd2837ec 100644 --- a/packages/global/core/workflow/template/system/http468.ts +++ b/packages/global/core/workflow/template/system/http468.ts @@ -44,6 +44,16 @@ export const HttpNode468: FlowNodeTemplateType = { value: 'POST', required: true }, + { + key: NodeInputKeyEnum.httpTimeout, + renderTypeList: [FlowNodeInputTypeEnum.custom], + valueType: WorkflowIOValueTypeEnum.number, + label: '', + value: 120, + min: 30, + max: 600, + required: true + }, { key: NodeInputKeyEnum.httpReqUrl, renderTypeList: [FlowNodeInputTypeEnum.hidden], diff --git a/packages/service/core/workflow/dispatch/tools/http468.ts b/packages/service/core/workflow/dispatch/tools/http468.ts index 216034b97..72eb168a2 100644 --- a/packages/service/core/workflow/dispatch/tools/http468.ts +++ b/packages/service/core/workflow/dispatch/tools/http468.ts @@ -57,6 +57,7 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise; body: Record | string; params: Record; + timeout: number; }) { const { data: response } = await axios({ method, @@ -215,7 +219,7 @@ async function fetchData({ 'Content-Type': 'application/json', ...headers }, - timeout: 120000, + timeout: timeout * 1000, params: params, data: ['POST', 'PUT', 'PATCH'].includes(method) ? body : undefined }); @@ -308,7 +312,7 @@ function replaceVariable(text: string, obj: Record) { replacement.startsWith('"') && replacement.endsWith('"') ? replacement.slice(1, -1) : replacement; - text = text.replace(new RegExp(`{{(${key})}}`, 'g'), unquotedReplacement); + text = text.replace(new RegExp(`{{(${key})}}`, 'g'), () => unquotedReplacement); } } return text || ''; diff --git a/packages/web/i18n/en/common.json b/packages/web/i18n/en/common.json index 6337140dd..31ea34242 100644 --- a/packages/web/i18n/en/common.json +++ b/packages/web/i18n/en/common.json @@ -617,7 +617,8 @@ "success": "Start syncing" } }, - "training": {} + "training": { + } }, "data": { "Auxiliary Data": "Auxiliary data", @@ -795,6 +796,7 @@ "Field Name": "Field name", "Http request props": "Request parameters", "Http request settings": "Request settings", + "Http timeout": "Timeout", "Input Type": "Input type", "Laf sync params": "Synchronize parameters", "Max Length": "Maximum length", diff --git a/packages/web/i18n/zh/common.json b/packages/web/i18n/zh/common.json index 739e9e5fb..61ec780d3 100644 --- a/packages/web/i18n/zh/common.json +++ b/packages/web/i18n/zh/common.json @@ -617,7 +617,8 @@ "success": "开始同步" } }, - "training": {} + "training": { + } }, "data": { "Auxiliary Data": "辅助数据", @@ -795,6 +796,7 @@ "Field Name": "字段名", "Http request props": "请求参数", "Http request settings": "请求配置", + "Http timeout": "超时时长", "Input Type": "输入类型", "Laf sync params": "同步参数", "Max Length": "最大长度", @@ -993,7 +995,6 @@ "Edit Folder": "编辑文件夹", "Edit Info": "编辑信息", "Export": "导出", - "dataset_name": "知识库名称", "Export Dataset Limit Error": "导出数据失败", "Folder Name": "输入文件夹名称", "Insert Data": "插入", @@ -1031,6 +1032,7 @@ }, "input is empty": "数据内容不能为空 " }, + "dataset_name": "知识库名称", "deleteFolderTips": "确认删除该文件夹及其包含的所有知识库?删除后数据无法恢复,请确认!", "test": { "noResult": "搜索结果为空" diff --git a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/NodeTemplatesModal.tsx b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/NodeTemplatesModal.tsx index c23407925..78747b4d9 100644 --- a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/NodeTemplatesModal.tsx +++ b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/NodeTemplatesModal.tsx @@ -92,7 +92,6 @@ const NodeTemplatesModal = ({ isOpen, onClose }: ModuleTemplateListProps) => { const { data: basicNodes } = useRequest2( async () => { if (templateType === TemplateTypeEnum.basic) { - console.log(1111); return basicNodeTemplates .filter((item) => { // unique node filter diff --git a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/NodeHttp/index.tsx b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/NodeHttp/index.tsx index 1a9fdfcba..2bc410e9d 100644 --- a/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/NodeHttp/index.tsx +++ b/projects/app/src/pages/app/detail/components/WorkflowComponents/Flow/nodes/NodeHttp/index.tsx @@ -17,7 +17,12 @@ import { Td, TableContainer, Button, - useDisclosure + useDisclosure, + NumberInputField, + NumberInputStepper, + NumberIncrementStepper, + NumberDecrementStepper, + NumberInput } from '@chakra-ui/react'; import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants'; import { useTranslation } from 'next-i18next'; @@ -372,6 +377,61 @@ export function RenderHttpProps({ return Render; } +const RenderHttpTimeout = ({ + nodeId, + inputs +}: { + nodeId: string; + inputs: FlowNodeInputItemType[]; +}) => { + const { t } = useTranslation(); + const timeout = inputs.find((item) => item.key === NodeInputKeyEnum.httpTimeout)!; + const [isEditTimeout, setIsEditTimeout] = useState(false); + const onChangeNode = useContextSelector(WorkflowContext, (v) => v.onChangeNode); + + return ( + + + + {t('common:core.module.Http timeout')} + + + {isEditTimeout ? ( + setIsEditTimeout(false)} + onChange={(e) => { + onChangeNode({ + nodeId, + type: 'updateInput', + key: NodeInputKeyEnum.httpTimeout, + value: { + ...timeout, + value: Number(e) + } + }); + }} + > + + + + + + + ) : ( + + )} + + + + ); +}; const RenderForm = ({ nodeId, input, @@ -643,11 +703,13 @@ const NodeHttp = ({ data, selected }: NodeProps) => { )); const Headers = useMemoizedFn(() => ); + const HttpTimeout = useMemoizedFn(() => ); const CustomComponents = useMemo(() => { return { [NodeInputKeyEnum.httpMethod]: HttpMethodAndUrl, - [NodeInputKeyEnum.httpHeaders]: Headers + [NodeInputKeyEnum.httpHeaders]: Headers, + [NodeInputKeyEnum.httpTimeout]: HttpTimeout }; }, [Headers, HttpMethodAndUrl]);