Skip to content

Commit

Permalink
node: improve GetActiveHandles performance
Browse files Browse the repository at this point in the history
Improve performance of process._getActiveHandles by sending handles in
batches to JS to be set on the passed Array. Add test to check proper
active handles are returned.

Alter implementation of GetActiveRequests to match GetActiveHandles'
implementation.

PR-URL: nodejs#3780
Reviewed-By: Fedor Indutny <[email protected]>
  • Loading branch information
trevnorris authored and Michael Scovetta committed Apr 2, 2016
1 parent 49d5f6b commit d986fd4
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 18 deletions.
40 changes: 22 additions & 18 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1608,27 +1608,21 @@ static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) {
Local<Array> ary = Array::New(args.GetIsolate());
Local<Context> ctx = env->context();
Local<Function> fn = env->push_values_to_array_function();
static const size_t argc = 8;
Local<Value> argv[argc];
size_t i = 0;
Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
size_t idx = 0;

for (auto w : *env->req_wrap_queue()) {
if (w->persistent().IsEmpty() == false) {
argv[i++ % argc] = w->object();
if ((i % argc) == 0) {
HandleScope scope(env->isolate());
fn->Call(ctx, ary, argc, argv).ToLocalChecked();
for (auto&& arg : argv) {
arg = Local<Value>();
}
}
if (w->persistent().IsEmpty())
continue;
argv[idx] = w->object();
if (++idx >= ARRAY_SIZE(argv)) {
fn->Call(ctx, ary, idx, argv).ToLocalChecked();
idx = 0;
}
}

const size_t remainder = i % argc;
if (remainder > 0) {
HandleScope scope(env->isolate());
fn->Call(ctx, ary, remainder, argv).ToLocalChecked();
if (idx > 0) {
fn->Call(ctx, ary, idx, argv).ToLocalChecked();
}

args.GetReturnValue().Set(ary);
Expand All @@ -1641,7 +1635,10 @@ void GetActiveHandles(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);

Local<Array> ary = Array::New(env->isolate());
int i = 0;
Local<Context> ctx = env->context();
Local<Function> fn = env->push_values_to_array_function();
Local<Value> argv[NODE_PUSH_VAL_TO_ARRAY_MAX];
size_t idx = 0;

Local<String> owner_sym = env->owner_string();

Expand All @@ -1652,7 +1649,14 @@ void GetActiveHandles(const FunctionCallbackInfo<Value>& args) {
Local<Value> owner = object->Get(owner_sym);
if (owner->IsUndefined())
owner = object;
ary->Set(i++, owner);
argv[idx] = owner;
if (++idx >= ARRAY_SIZE(argv)) {
fn->Call(ctx, ary, idx, argv).ToLocalChecked();
idx = 0;
}
}
if (idx > 0) {
fn->Call(ctx, ary, idx, argv).ToLocalChecked();
}

args.GetReturnValue().Set(ary);
Expand Down
44 changes: 44 additions & 0 deletions test/parallel/test-process-getactivehandles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
'use strict';

const common = require('../common');
const assert = require('assert');
const net = require('net');
const NUM = 8;
const connections = [];
const clients = [];
var clients_counter = 0;

const server = net.createServer(function listener(c) {
connections.push(c);
}).listen(common.PORT, function makeConnections() {
for (var i = 0; i < NUM; i++) {
net.connect(common.PORT, function connected() {
clientConnected(this);
});
}
});


function clientConnected(client) {
clients.push(client);
if (++clients_counter >= NUM)
checkAll();
}


function checkAll() {
const handles = process._getActiveHandles();

clients.forEach(function(item) {
assert.ok(handles.indexOf(item) > -1);
item.destroy();
});

connections.forEach(function(item) {
assert.ok(handles.indexOf(item) > -1);
item.end();
});

assert.ok(handles.indexOf(server) > -1);
server.close();
}

0 comments on commit d986fd4

Please sign in to comment.