Node.js: napi_call_function() replaced with napi_make_callback().

The sequence of napi_open_callback_scope(),
napi_call_function(), and napi_close_callback_scope() functions calls
executes the provided JS code and all functions enqueued by
process.nextTick() and Promises during this execution.
This commit is contained in:
Alexander Borisov
2018-12-19 15:56:01 +03:00
parent 13c9ebccca
commit f47a5db506
2 changed files with 63 additions and 27 deletions

View File

@@ -342,7 +342,7 @@ Server.prototype.listen = function () {
this.unit.listen();
};
Server.prototype.run_events = function (server, req, res) {
Server.prototype.emit_events = function (server, req, res) {
req.server = server;
res.server = server;
req.res = res;
@@ -350,18 +350,11 @@ Server.prototype.run_events = function (server, req, res) {
server.buffer = server.unit._read(req.socket.req_pointer);
/* Important!!! setImmediate starts the next iteration in Node.js loop. */
setImmediate(function () {
server.emit("request", req, res);
Promise.resolve().then(() => {
process.nextTick(() => {
req.emit("finish");
req.emit("end");
if (res.finished) {
unit_lib.unit_response_end(res);
}
});
});
};

View File

@@ -277,10 +277,11 @@ void
Unit::request_handler(nxt_unit_request_info_t *req)
{
Unit *obj;
napi_value socket, request, response;
napi_value global, server_obj;
napi_value run_events, events_res;
napi_value socket, request, response, global, server_obj;
napi_value emit_events, events_res, async_name, resource_object;
napi_status status;
napi_async_context async_context;
napi_callback_scope async_scope;
napi_value events_args[3];
obj = reinterpret_cast<Unit *>(req->unit->data);
@@ -328,11 +329,11 @@ Unit::request_handler(nxt_unit_request_info_t *req)
return;
}
status = napi_get_named_property(obj->env_, server_obj, "run_events",
&run_events);
status = napi_get_named_property(obj->env_, server_obj, "emit_events",
&emit_events);
if (status != napi_ok) {
napi_throw_error(obj->env_, NULL, "Failed to get "
" 'run_events' function");
"'emit_events' function");
return;
}
@@ -340,15 +341,57 @@ Unit::request_handler(nxt_unit_request_info_t *req)
events_args[1] = request;
events_args[2] = response;
status = napi_call_function(obj->env_, server_obj, run_events, 3,
events_args, &events_res);
status = napi_create_string_utf8(obj->env_, "unit_request_handler",
sizeof("unit_request_handler") - 1,
&async_name);
if (status != napi_ok) {
napi_throw_error(obj->env_, NULL, "Failed to call"
" 'run_events' function");
napi_throw_error(obj->env_, NULL, "Failed to create utf-8 string");
return;
}
napi_close_handle_scope(obj->env_, scope);
status = napi_async_init(obj->env_, NULL, async_name, &async_context);
if (status != napi_ok) {
napi_throw_error(obj->env_, NULL, "Failed to init async object");
return;
}
status = napi_create_object(obj->env_, &resource_object);
if (status != napi_ok) {
napi_throw_error(obj->env_, NULL, "Failed to create object for "
"callback scope");
return;
}
status = napi_open_callback_scope(obj->env_, resource_object, async_context,
&async_scope);
if (status != napi_ok) {
napi_throw_error(obj->env_, NULL, "Failed to open callback scope");
return;
}
status = napi_make_callback(obj->env_, async_context, server_obj,
emit_events, 3, events_args, &events_res);
if (status != napi_ok) {
napi_throw_error(obj->env_, NULL, "Failed to make callback");
return;
}
status = napi_close_callback_scope(obj->env_, async_scope);
if (status != napi_ok) {
napi_throw_error(obj->env_, NULL, "Failed to close callback scope");
return;
}
status = napi_async_destroy(obj->env_, async_context);
if (status != napi_ok) {
napi_throw_error(obj->env_, NULL, "Failed to destroy async object");
return;
}
status = napi_close_handle_scope(obj->env_, scope);
if (status != napi_ok) {
napi_throw_error(obj->env_, NULL, "Failed to close handle scope");
}
}