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 <fedor@indutny.com>
  • Loading branch information
trevnorris authored and Fishrock123 committed Jan 6, 2016
1 parent e742422 commit c8fc217
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 c8fc217

Please sign in to comment.