使用 node.js 客户端的网络超时大约 5 秒
Network timeout using node.js client at about 5 seconds
注意,这个问题以前是非常不同的。这才是真正的问题。这是...
当使用 node.js client 调用 executeStoredProcedure() 时,我得到一个 408 代码,RequestTimeout,并且我没有从存储过程的 "body" 返回任何数据。这似乎发生在大约 5 秒时,但是当我从 sproc 本身内部对事物进行时间限制时,任何超过 700 毫秒的值都会导致我获得网络超时(尽管我直到大约 5 秒后才看到它)。
请注意,我可以使用更长的 运行 存储过程进行读取操作。这似乎只有在我有很多 createDocument() 操作时才会发生,所以我认为它不在客户端。我认为服务器端发生了一些事情。
我最初的想法仍然有可能是正确的,并且我没有从 createDocument() 调用中得到错误返回,这导致我的存储过程保持 运行 超过其超时,这就是导致 408 的原因。
这是我创建文件sproc的限时版本
generateData = function(memo) {
var collection, collectionLink, nowTime, row, startTime, timeout;
if ((memo != null ? memo.remaining : void 0) == null) {
throw new Error('generateData must be called with an object containing a `remaining` field.');
}
if (memo.totalCount == null) {
memo.totalCount = 0;
}
memo.countForThisRun = 0;
timeout = memo.timeout || 600; // Works at 600. Fails at 800.
startTime = new Date();
memo.stillTime = true;
collection = getContext().getCollection();
collectionLink = collection.getSelfLink();
memo.stillQueueing = true;
while (memo.remaining > 0 && memo.stillQueueing && memo.stillTime) {
row = {
a: 1,
b: 2
};
getContext().getResponse().setBody(memo);
memo.stillQueueing = collection.createDocument(collectionLink, row);
if (memo.stillQueueing) {
memo.remaining--;
memo.countForThisRun++;
memo.totalCount++;
}
nowTime = new Date();
memo.nowTime = nowTime;
memo.startTime = startTime;
memo.stillTime = (nowTime - startTime) < timeout;
if (memo.stillTime) {
memo.continuation = null;
} else {
memo.continuation = 'Value does not matter';
}
}
getContext().getResponse().setBody(memo);
return memo;
};
上面的存储过程在 while 循环中创建队列文档,直到 API returns false
.
请记住 createDocument()
是一种异步方法。布尔值 returned 表示是否该立即结束执行。 return 值不足以 "smart" 来估计和说明异步调用将花费多少时间;所以它不能用于在 while() 循环中对一堆调用进行排队。
因此,当布尔值 returns false
时,上面的存储过程不会正常终止,因为它有一堆 createDocument() 调用仍然是 运行 .最终结果是超时(最终导致重复尝试被列入黑名单)。
简而言之,避免这种模式:
while (stillQueueing) {
stillQueueing = collection.createDocument(collectionLink, row);
}
相反,您应该使用回调来控制流程。这是重构后的代码:
function(memo) {
var collection = getContext().getCollection();
var collectionLink = collection.getSelfLink();
var row = {
a: 1,
b: 2
};
if ((memo != null ? memo.remaining : void 0) == null) {
throw new Error('generateData must be called with an object containing a `remaining` field.');
}
if (memo.totalCount == null) {
memo.totalCount = 0;
}
memo.countForThisRun = 0;
createMemo();
function createMemo() {
var isAccepted = collection.createDocument(collectionLink, row, function(err, createdDoc) {
if (err) throw err;
memo.remaining--;
memo.countForThisRun++;
memo.totalCount++;
if (memo.remaining > 0) {
createMemo();
} else {
getContext().getResponse().setBody(memo);
}
});
if (!isAccepted) {
getContext().getResponse().setBody(memo);
}
}
};
注意,这个问题以前是非常不同的。这才是真正的问题。这是...
当使用 node.js client 调用 executeStoredProcedure() 时,我得到一个 408 代码,RequestTimeout,并且我没有从存储过程的 "body" 返回任何数据。这似乎发生在大约 5 秒时,但是当我从 sproc 本身内部对事物进行时间限制时,任何超过 700 毫秒的值都会导致我获得网络超时(尽管我直到大约 5 秒后才看到它)。
请注意,我可以使用更长的 运行 存储过程进行读取操作。这似乎只有在我有很多 createDocument() 操作时才会发生,所以我认为它不在客户端。我认为服务器端发生了一些事情。
我最初的想法仍然有可能是正确的,并且我没有从 createDocument() 调用中得到错误返回,这导致我的存储过程保持 运行 超过其超时,这就是导致 408 的原因。
这是我创建文件sproc的限时版本
generateData = function(memo) {
var collection, collectionLink, nowTime, row, startTime, timeout;
if ((memo != null ? memo.remaining : void 0) == null) {
throw new Error('generateData must be called with an object containing a `remaining` field.');
}
if (memo.totalCount == null) {
memo.totalCount = 0;
}
memo.countForThisRun = 0;
timeout = memo.timeout || 600; // Works at 600. Fails at 800.
startTime = new Date();
memo.stillTime = true;
collection = getContext().getCollection();
collectionLink = collection.getSelfLink();
memo.stillQueueing = true;
while (memo.remaining > 0 && memo.stillQueueing && memo.stillTime) {
row = {
a: 1,
b: 2
};
getContext().getResponse().setBody(memo);
memo.stillQueueing = collection.createDocument(collectionLink, row);
if (memo.stillQueueing) {
memo.remaining--;
memo.countForThisRun++;
memo.totalCount++;
}
nowTime = new Date();
memo.nowTime = nowTime;
memo.startTime = startTime;
memo.stillTime = (nowTime - startTime) < timeout;
if (memo.stillTime) {
memo.continuation = null;
} else {
memo.continuation = 'Value does not matter';
}
}
getContext().getResponse().setBody(memo);
return memo;
};
上面的存储过程在 while 循环中创建队列文档,直到 API returns false
.
请记住 createDocument()
是一种异步方法。布尔值 returned 表示是否该立即结束执行。 return 值不足以 "smart" 来估计和说明异步调用将花费多少时间;所以它不能用于在 while() 循环中对一堆调用进行排队。
因此,当布尔值 returns false
时,上面的存储过程不会正常终止,因为它有一堆 createDocument() 调用仍然是 运行 .最终结果是超时(最终导致重复尝试被列入黑名单)。
简而言之,避免这种模式:
while (stillQueueing) {
stillQueueing = collection.createDocument(collectionLink, row);
}
相反,您应该使用回调来控制流程。这是重构后的代码:
function(memo) {
var collection = getContext().getCollection();
var collectionLink = collection.getSelfLink();
var row = {
a: 1,
b: 2
};
if ((memo != null ? memo.remaining : void 0) == null) {
throw new Error('generateData must be called with an object containing a `remaining` field.');
}
if (memo.totalCount == null) {
memo.totalCount = 0;
}
memo.countForThisRun = 0;
createMemo();
function createMemo() {
var isAccepted = collection.createDocument(collectionLink, row, function(err, createdDoc) {
if (err) throw err;
memo.remaining--;
memo.countForThisRun++;
memo.totalCount++;
if (memo.remaining > 0) {
createMemo();
} else {
getContext().getResponse().setBody(memo);
}
});
if (!isAccepted) {
getContext().getResponse().setBody(memo);
}
}
};