worker: add cpuUsage for worker · nodejs/node@bd68fbd

@@ -32,6 +32,7 @@ using v8::Isolate;

3232

using v8::Local;

3333

using v8::Locker;

3434

using v8::Maybe;

35+

using v8::Name;

3536

using v8::Null;

3637

using v8::Number;

3738

using v8::Object;

@@ -810,6 +811,81 @@ void Worker::Unref(const FunctionCallbackInfo<Value>& args) {

810811

}

811812

}

812813814+

class WorkerCpuUsageTaker : public AsyncWrap {

815+

public:

816+

WorkerCpuUsageTaker(Environment* env, Local<Object> obj)

817+

: AsyncWrap(env, obj, AsyncWrap::PROVIDER_WORKERCPUUSAGE) {}

818+819+

SET_NO_MEMORY_INFO()

820+

SET_MEMORY_INFO_NAME(WorkerCpuUsageTaker)

821+

SET_SELF_SIZE(WorkerCpuUsageTaker)

822+

};

823+824+

void Worker::CpuUsage(const FunctionCallbackInfo<Value>& args) {

825+

Worker* w;

826+

ASSIGN_OR_RETURN_UNWRAP(&w, args.This());

827+828+

Environment* env = w->env();

829+

AsyncHooks::DefaultTriggerAsyncIdScope trigger_id_scope(w);

830+

Local<Object> wrap;

831+

if (!env->worker_cpu_usage_taker_template()

832+

->NewInstance(env->context())

833+

.ToLocal(&wrap)) {

834+

return;

835+

}

836+837+

BaseObjectPtr<WorkerCpuUsageTaker> taker =

838+

MakeDetachedBaseObject<WorkerCpuUsageTaker>(env, wrap);

839+840+

bool scheduled = w->RequestInterrupt([taker = std::move(taker),

841+

env](Environment* worker_env) mutable {

842+

auto cpu_usage_stats = std::make_unique<uv_rusage_t>();

843+

int err = uv_getrusage_thread(cpu_usage_stats.get());

844+845+

env->SetImmediateThreadsafe(

846+

[taker = std::move(taker),

847+

cpu_usage_stats = std::move(cpu_usage_stats),

848+

err = err](Environment* env) mutable {

849+

Isolate* isolate = env->isolate();

850+

HandleScope handle_scope(isolate);

851+

Context::Scope context_scope(env->context());

852+

AsyncHooks::DefaultTriggerAsyncIdScope trigger_id_scope(taker.get());

853+854+

Local<Value> argv[] = {

855+

Null(isolate),

856+

Undefined(isolate),

857+

};

858+859+

if (err) {

860+

argv[0] = UVException(

861+

isolate, err, "uv_getrusage_thread", nullptr, nullptr, nullptr);

862+

} else {

863+

Local<Name> names[] = {

864+

FIXED_ONE_BYTE_STRING(isolate, "user"),

865+

FIXED_ONE_BYTE_STRING(isolate, "system"),

866+

};

867+

Local<Value> values[] = {

868+

Number::New(isolate,

869+

1e6 * cpu_usage_stats->ru_utime.tv_sec +

870+

cpu_usage_stats->ru_utime.tv_usec),

871+

Number::New(isolate,

872+

1e6 * cpu_usage_stats->ru_stime.tv_sec +

873+

cpu_usage_stats->ru_stime.tv_usec),

874+

};

875+

argv[1] = Object::New(

876+

isolate, Null(isolate), names, values, arraysize(names));

877+

}

878+879+

taker->MakeCallback(env->ondone_string(), arraysize(argv), argv);

880+

},

881+

CallbackFlags::kUnrefed);

882+

});

883+884+

if (scheduled) {

885+

args.GetReturnValue().Set(wrap);

886+

}

887+

}

888+813889

class WorkerHeapStatisticsTaker : public AsyncWrap {

814890

public:

815891

WorkerHeapStatisticsTaker(Environment* env, Local<Object> obj)

@@ -1101,6 +1177,7 @@ void CreateWorkerPerIsolateProperties(IsolateData* isolate_data,

11011177

SetProtoMethod(isolate, w, "loopIdleTime", Worker::LoopIdleTime);

11021178

SetProtoMethod(isolate, w, "loopStartTime", Worker::LoopStartTime);

11031179

SetProtoMethod(isolate, w, "getHeapStatistics", Worker::GetHeapStatistics);

1180+

SetProtoMethod(isolate, w, "cpuUsage", Worker::CpuUsage);

1104118111051182

SetConstructorFunction(isolate, target, "Worker", w);

11061183

}

@@ -1133,6 +1210,19 @@ void CreateWorkerPerIsolateProperties(IsolateData* isolate_data,

11331210

wst->InstanceTemplate());

11341211

}

113512121213+

{

1214+

Local<FunctionTemplate> wst = NewFunctionTemplate(isolate, nullptr);

1215+1216+

wst->InstanceTemplate()->SetInternalFieldCount(

1217+

WorkerCpuUsageTaker::kInternalFieldCount);

1218+

wst->Inherit(AsyncWrap::GetConstructorTemplate(isolate_data));

1219+1220+

Local<String> wst_string =

1221+

FIXED_ONE_BYTE_STRING(isolate, "WorkerCpuUsageTaker");

1222+

wst->SetClassName(wst_string);

1223+

isolate_data->set_worker_cpu_usage_taker_template(wst->InstanceTemplate());

1224+

}

1225+11361226

SetMethod(isolate, target, "getEnvMessagePort", GetEnvMessagePort);

11371227

}

11381228

@@ -1199,6 +1289,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {

11991289

registry->Register(Worker::LoopIdleTime);

12001290

registry->Register(Worker::LoopStartTime);

12011291

registry->Register(Worker::GetHeapStatistics);

1292+

registry->Register(Worker::CpuUsage);

12021293

}

1203129412041295

} // anonymous namespace