feat: add http node timeout (#2465)

* fix $ in replacement string misinterpreted as regex special character

* add http timeout

* delete console log
This commit is contained in:
heheer
2024-08-21 20:23:35 +08:00
committed by GitHub
parent 113c57bcbe
commit 5627a4bfde
7 changed files with 90 additions and 10 deletions

View File

@@ -105,6 +105,7 @@ export enum NodeInputKeyEnum {
httpMethod = 'system_httpMethod',
httpParams = 'system_httpParams',
httpJsonBody = 'system_httpJsonBody',
httpTimeout = 'system_httpTimeout',
abandon_httpUrl = 'url',
// app

View File

@@ -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],

View File

@@ -57,6 +57,7 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H
system_httpHeader: httpHeader,
system_httpParams: httpParams = [],
system_httpJsonBody: httpJsonBody,
system_httpTimeout: httpTimeout,
[NodeInputKeyEnum.addInputParam]: dynamicInput,
...body
}
@@ -143,7 +144,8 @@ export const dispatchHttp468Request = async (props: HttpRequestProps): Promise<H
url: httpReqUrl,
headers,
body: requestBody,
params
params,
timeout: httpTimeout
});
})();
@@ -199,13 +201,15 @@ async function fetchData({
url,
headers,
body,
params
params,
timeout
}: {
method: string;
url: string;
headers: Record<string, any>;
body: Record<string, any> | string;
params: Record<string, any>;
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<string, any>) {
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 || '';

View File

@@ -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",

View File

@@ -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": "搜索结果为空"

View File

@@ -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

View File

@@ -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 (
<Box>
<Box mb={2} display={'flex'} justifyContent={'space-between'}>
<Box fontWeight={'medium'} color={'myGray.600'}>
{t('common:core.module.Http timeout')}
</Box>
<Box>
{isEditTimeout ? (
<NumberInput
defaultValue={timeout.value}
min={timeout.min}
max={timeout.max}
onBlur={() => setIsEditTimeout(false)}
onChange={(e) => {
onChangeNode({
nodeId,
type: 'updateInput',
key: NodeInputKeyEnum.httpTimeout,
value: {
...timeout,
value: Number(e)
}
});
}}
>
<NumberInputField bg={'white'} px={3} borderRadius={'sm'} />
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
</NumberInputStepper>
</NumberInput>
) : (
<Button
variant={'ghost'}
color={'myGray.600'}
onClick={() => setIsEditTimeout(true)}
>{`${timeout?.value} s`}</Button>
)}
</Box>
</Box>
</Box>
);
};
const RenderForm = ({
nodeId,
input,
@@ -643,11 +703,13 @@ const NodeHttp = ({ data, selected }: NodeProps<FlowNodeItemType>) => {
<RenderHttpMethodAndUrl nodeId={nodeId} inputs={inputs} />
));
const Headers = useMemoizedFn(() => <RenderHttpProps nodeId={nodeId} inputs={inputs} />);
const HttpTimeout = useMemoizedFn(() => <RenderHttpTimeout nodeId={nodeId} inputs={inputs} />);
const CustomComponents = useMemo(() => {
return {
[NodeInputKeyEnum.httpMethod]: HttpMethodAndUrl,
[NodeInputKeyEnum.httpHeaders]: Headers
[NodeInputKeyEnum.httpHeaders]: Headers,
[NodeInputKeyEnum.httpTimeout]: HttpTimeout
};
}, [Headers, HttpMethodAndUrl]);