node.js 超时重启 api 调用
node.js timeout restarts api call
平台:
我在 sails.js and a frontend in react. The calls between front and back end are being made with fetch api 中有一个 api。
更多信息:
在某些api端点的过程中我必须执行一个外部文件,此时我使用的是execfile() function of node.js,我必须等待它被执行以响应前端。
问题是什么?
如果文件在短时间内执行,例如不到 1 分钟,一切都很好 运行 并且双方都按预期发生行为,但如果(在这种情况下)文件需要更多执行时间超过 1 分钟,有一些东西可以触发对 api 的第二次调用(我不知道这是在哪里调用的,但我用 postman 测试了同一个端点,我没有这个问题所以我怀疑 react / fetch-api) 和 api 调用与第一次调用相同的数据被重做。这会导致文件 运行 两次。
更奇怪的是,如果您打开了 DevTools 网络检查器,则不会出现第二次调用,但 sailjs 的文档中没有任何内容指向此行为。
sails.js中的端点示例:
/**
* FooController
*/
const execFile = require("child_process").execFile;
module.exports = {
foo: async (req, res) => {
let result = await module.exports._executeScript(req.body).catch(() => {
res.status(500).json({ error: "something has occurred" });
});
res.json(result);
},
_executeScript: body => {
return new Promise((resolve, reject) => {
let args = [process.cwd() + "/scripts/" + "myExternalFile.js", body];
let elem = await module.exports
._execScript(args)
.catch(err => reject(err));
resolve(elem);
});
},
_execScript: args => {
return new Promise((resolve, reject) => {
try {
execFile("node", args, { timeout: 150000 }, (error, stdout, stderr) => {
if (error || (stderr != null && stderr !== "")) {
console.error(error);
} else {
console.log(stdout);
}
let output = { stdout: stdout, stderr: stderr };
resolve(output);
});
} catch (err) {
reject(err);
}
});
}
};
组件对获取调用的反应示例:
import React from "react";
import { notification } from "antd";
import "./../App.css";
import Oauth from "./../helper/Oauth";
import Config from "./../config.json";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
syncInAction: false,
data: null
};
}
componentDidMount() {
this.handleSync();
}
async handleSync() {
let response = await fetch(Config.apiLink + "/foo/foo", {
method: "POST",
mode: "cors",
headers: {
Authorization: Oauth.isLoggedIn(),
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(this.state.myData)
}).catch(err => {
notification.error({
key: "catch-ApiFail",
message: "Erro"
});
});
let json = await response.json();
this.setState({
syncInAction: false,
data: json
});
}
render() {
return <div>{this.state.data}</div>;
}
}
export default App;
我的预期目标/行为是什么:
无论调用1分钟还是10小时都无所谓,文件只能调用一次,调用完成后,可以return到前端。
请注意,示例没有原始代码,也没有经过测试。是解释行为的代码的简化版本
我最终解决了这个问题,显然 nodejs has a default timing of 2 minutes 在服务器上,并且可以重写以忽略此超时或增加它。
这只是在 foo() 端点的开头添加一行代码,问题就解决了。
重做调用的行为是没有文档记录的,使用postman时没有这个行为很奇怪,但是这里有谁需要的解决方法。
最终结果:
foo: async (req, res) => {
req.setTimeout(0);
let result = await module.exports._executeScript(req.body).catch(() => {
res.status(500).json({ error: "something has occurred" });
});
res.json(result);
};
平台:
我在 sails.js and a frontend in react. The calls between front and back end are being made with fetch api 中有一个 api。
更多信息:
在某些api端点的过程中我必须执行一个外部文件,此时我使用的是execfile() function of node.js,我必须等待它被执行以响应前端。
问题是什么?
如果文件在短时间内执行,例如不到 1 分钟,一切都很好 运行 并且双方都按预期发生行为,但如果(在这种情况下)文件需要更多执行时间超过 1 分钟,有一些东西可以触发对 api 的第二次调用(我不知道这是在哪里调用的,但我用 postman 测试了同一个端点,我没有这个问题所以我怀疑 react / fetch-api) 和 api 调用与第一次调用相同的数据被重做。这会导致文件 运行 两次。
更奇怪的是,如果您打开了 DevTools 网络检查器,则不会出现第二次调用,但 sailjs 的文档中没有任何内容指向此行为。
sails.js中的端点示例:
/**
* FooController
*/
const execFile = require("child_process").execFile;
module.exports = {
foo: async (req, res) => {
let result = await module.exports._executeScript(req.body).catch(() => {
res.status(500).json({ error: "something has occurred" });
});
res.json(result);
},
_executeScript: body => {
return new Promise((resolve, reject) => {
let args = [process.cwd() + "/scripts/" + "myExternalFile.js", body];
let elem = await module.exports
._execScript(args)
.catch(err => reject(err));
resolve(elem);
});
},
_execScript: args => {
return new Promise((resolve, reject) => {
try {
execFile("node", args, { timeout: 150000 }, (error, stdout, stderr) => {
if (error || (stderr != null && stderr !== "")) {
console.error(error);
} else {
console.log(stdout);
}
let output = { stdout: stdout, stderr: stderr };
resolve(output);
});
} catch (err) {
reject(err);
}
});
}
};
组件对获取调用的反应示例:
import React from "react";
import { notification } from "antd";
import "./../App.css";
import Oauth from "./../helper/Oauth";
import Config from "./../config.json";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
syncInAction: false,
data: null
};
}
componentDidMount() {
this.handleSync();
}
async handleSync() {
let response = await fetch(Config.apiLink + "/foo/foo", {
method: "POST",
mode: "cors",
headers: {
Authorization: Oauth.isLoggedIn(),
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(this.state.myData)
}).catch(err => {
notification.error({
key: "catch-ApiFail",
message: "Erro"
});
});
let json = await response.json();
this.setState({
syncInAction: false,
data: json
});
}
render() {
return <div>{this.state.data}</div>;
}
}
export default App;
我的预期目标/行为是什么:
无论调用1分钟还是10小时都无所谓,文件只能调用一次,调用完成后,可以return到前端。
请注意,示例没有原始代码,也没有经过测试。是解释行为的代码的简化版本
我最终解决了这个问题,显然 nodejs has a default timing of 2 minutes 在服务器上,并且可以重写以忽略此超时或增加它。 这只是在 foo() 端点的开头添加一行代码,问题就解决了。
重做调用的行为是没有文档记录的,使用postman时没有这个行为很奇怪,但是这里有谁需要的解决方法。
最终结果:
foo: async (req, res) => {
req.setTimeout(0);
let result = await module.exports._executeScript(req.body).catch(() => {
res.status(500).json({ error: "something has occurred" });
});
res.json(result);
};