一些 progress.Send 调用没有进入 nodejs 土地
Some progress.Send calls not making it to nodejs land
我已经使用 AsyncProgressWorker 线程制作了一个 Node 插件来处理我的套接字消息。这是我的代码:
class ProgressWorker : public AsyncProgressWorker {
public:
ProgressWorker(
Callback *callback
, Callback *progress)
: AsyncProgressWorker(callback), progress(progress) {}
~ProgressWorker() {}
void Execute (const AsyncProgressWorker::ExecutionProgress& progress) {
char response[4096];
int result;
int connected = 1;
int timeout = 0;
int pending = 0;
while(connected) {
result = sctp_recvmsg(sock, (void *)&response, (size_t)sizeof(response), NULL, 0, 0, 0);
if (result > 0 && result < 4095) {
if (debug) {
printf("Server replied (size %d)\n", result);
}
pending = 0;
progress.Send((const char *)response, size_t(result));
result = 0;
}
else {
// Don't mind my timeout mechanism. :))
if ((result == -1 && errno != EWOULDBLOCK) || pending) {
if (timeout == 0) {
printf("Can't receive from other end. Waiting for 3 seconds. Error code: %d\n", errno);
pending = 1;
}
if (timeout >= 3000) {
connected = 0;
close(sock);
}
else {
timeout += 5;
usleep(5000);
}
}
else {
usleep(5000);
}
}
}
}
void HandleProgressCallback(const char *data, size_t count) {
HandleScope scope;
v8::Local<v8::Value> argv[] = {
CopyBuffer(const_cast<char*>(data), count).ToLocalChecked()
};
progress->Call(1, argv); // This is the callback to nodejs
}
private:
Callback *progress;
};
直到今晚我才对此进行压力测试,然后我注意到有些消息无法返回到节点。它将打印我的 "Server replied" 调试日志,但不会记录我放在进度回调中的调试日志。我在这里错过了什么吗?提前致谢。
AsyncProgressWorker
基于一个uv_async_t
,它允许任何线程唤醒主线程。但是,如 documentation:
中所述
libuv will coalesce calls to uv_async_send(), that is, not every call
to it will yield an execution of the callback. For example: if
uv_async_send() is called 5 times in a row before the callback is
called, the callback will only be called once. If uv_async_send() is
called again after the callback was called, it will be called again.
^^ 这就是您的应用程序在压力下有时可能收不到某些事件的原因。这条线上方是问题的答案。以下是我的 "above and beyond" 可能的解决方案来处理您的问题:
碰巧我正在努力为 AsyncProgressWorker
添加一个新的替代方案,它承诺提供 每个 事件,就像 AsyncProgressWorker
所做的那样,但是使用队列。此功能最近已合并到 NAN 中。如果你想测试它,试试 https://github.com/nodejs/nan 的 git 存储库,然后用 AsyncProgressQueueWorker<char>
替换你的 AsyncProgressWorker
重新 运行 你的测试和所有事件即将发货。
添加此新功能的拉取请求在这里:https://github.com/nodejs/nan/pull/692 - 2017 年 10 月 6 日合并。
此新功能已在 NAN 版本 2.8.0
中发布
您可以通过更改 package.json
以使用 nan 2.8.0 或更高版本来使用这个新的 class 模板:
"dependencies": {
"nan": "^2.8.0"
},
我已经使用 AsyncProgressWorker 线程制作了一个 Node 插件来处理我的套接字消息。这是我的代码:
class ProgressWorker : public AsyncProgressWorker {
public:
ProgressWorker(
Callback *callback
, Callback *progress)
: AsyncProgressWorker(callback), progress(progress) {}
~ProgressWorker() {}
void Execute (const AsyncProgressWorker::ExecutionProgress& progress) {
char response[4096];
int result;
int connected = 1;
int timeout = 0;
int pending = 0;
while(connected) {
result = sctp_recvmsg(sock, (void *)&response, (size_t)sizeof(response), NULL, 0, 0, 0);
if (result > 0 && result < 4095) {
if (debug) {
printf("Server replied (size %d)\n", result);
}
pending = 0;
progress.Send((const char *)response, size_t(result));
result = 0;
}
else {
// Don't mind my timeout mechanism. :))
if ((result == -1 && errno != EWOULDBLOCK) || pending) {
if (timeout == 0) {
printf("Can't receive from other end. Waiting for 3 seconds. Error code: %d\n", errno);
pending = 1;
}
if (timeout >= 3000) {
connected = 0;
close(sock);
}
else {
timeout += 5;
usleep(5000);
}
}
else {
usleep(5000);
}
}
}
}
void HandleProgressCallback(const char *data, size_t count) {
HandleScope scope;
v8::Local<v8::Value> argv[] = {
CopyBuffer(const_cast<char*>(data), count).ToLocalChecked()
};
progress->Call(1, argv); // This is the callback to nodejs
}
private:
Callback *progress;
};
直到今晚我才对此进行压力测试,然后我注意到有些消息无法返回到节点。它将打印我的 "Server replied" 调试日志,但不会记录我放在进度回调中的调试日志。我在这里错过了什么吗?提前致谢。
AsyncProgressWorker
基于一个uv_async_t
,它允许任何线程唤醒主线程。但是,如 documentation:
libuv will coalesce calls to uv_async_send(), that is, not every call to it will yield an execution of the callback. For example: if uv_async_send() is called 5 times in a row before the callback is called, the callback will only be called once. If uv_async_send() is called again after the callback was called, it will be called again.
^^ 这就是您的应用程序在压力下有时可能收不到某些事件的原因。这条线上方是问题的答案。以下是我的 "above and beyond" 可能的解决方案来处理您的问题:
碰巧我正在努力为 AsyncProgressWorker
添加一个新的替代方案,它承诺提供 每个 事件,就像 AsyncProgressWorker
所做的那样,但是使用队列。此功能最近已合并到 NAN 中。如果你想测试它,试试 https://github.com/nodejs/nan 的 git 存储库,然后用 AsyncProgressQueueWorker<char>
替换你的 AsyncProgressWorker
重新 运行 你的测试和所有事件即将发货。
添加此新功能的拉取请求在这里:https://github.com/nodejs/nan/pull/692 - 2017 年 10 月 6 日合并。
此新功能已在 NAN 版本 2.8.0
中发布您可以通过更改 package.json
以使用 nan 2.8.0 或更高版本来使用这个新的 class 模板:
"dependencies": {
"nan": "^2.8.0"
},