Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

domain: runtime deprecate MakeCallback #17417

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions doc/api/deprecations.md
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,15 @@ Type: Runtime

`timers.unenroll()` is deprecated. Please use the publicly documented [`clearTimeout()`][] or [`clearInterval()`][] instead.

<a id="DEP00XX"></a>
### MakeCallback with domain property

Type: Runtime

Users of `MakeCallback` that add the `domain` property to carry context,
should start using the `async_context` variant of `MakeCallback` or
`CallbackScope`, or the the high-level `AsyncResource` class.

[`--pending-deprecation`]: cli.html#cli_pending_deprecation
[`Buffer.allocUnsafeSlow(size)`]: buffer.html#buffer_class_method_buffer_allocunsafeslow_size
[`Buffer.from(array)`]: buffer.html#buffer_class_method_buffer_from_array
Expand Down
16 changes: 16 additions & 0 deletions lib/domain.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,29 @@ process.setUncaughtExceptionCaptureCallback = function(fn) {
throw err;
};


let sendMakeCallbackDeprecation = false;
function emitMakeCallbackDeprecation() {
if (!sendMakeCallbackDeprecation) {
process.emitWarning(
'Using a domain property in MakeCallback is deprecated. Use the ' +
'async_context variant of MakeCallback or the AsyncResource class ' +
'instead.', 'DeprecationWarning', 'DEP00XX');
sendMakeCallbackDeprecation = true;
}
}

function topLevelDomainCallback(cb, ...args) {
const domain = this.domain;
if (exports.active && domain)
emitMakeCallbackDeprecation();

if (domain)
domain.enter();
const ret = Reflect.apply(cb, this, args);
if (domain)
domain.exit();

return ret;
}

Expand Down
31 changes: 31 additions & 0 deletions test/addons/make-callback-domain-warning/binding.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "node.h"
#include "v8.h"

#include <assert.h>

using v8::Function;
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::Value;

namespace {

void MakeCallback(const FunctionCallbackInfo<Value>& args) {
assert(args[0]->IsObject());
assert(args[1]->IsFunction());
Isolate* isolate = args.GetIsolate();
Local<Object> recv = args[0].As<Object>();
Local<Function> method = args[1].As<Function>();

node::MakeCallback(isolate, recv, method, 0, nullptr);
}

void Initialize(Local<Object> exports) {
NODE_SET_METHOD(exports, "makeCallback", MakeCallback);
}

} // namespace

NODE_MODULE(NODE_GYP_MODULE_NAME, Initialize)
9 changes: 9 additions & 0 deletions test/addons/make-callback-domain-warning/binding.gyp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
'targets': [
{
'target_name': 'binding',
'defines': [ 'V8_DEPRECATION_WARNINGS=1' ],
'sources': [ 'binding.cc' ]
}
]
}
35 changes: 35 additions & 0 deletions test/addons/make-callback-domain-warning/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use strict';

const common = require('../../common');
const assert = require('assert');
const domain = require('domain');
const binding = require(`./build/${common.buildType}/binding`);

function makeCallback(object, cb) {
binding.makeCallback(object, () => setImmediate(cb));
}

let latestWarning = null;
process.on('warning', function(warning) {
latestWarning = warning;
});

const d = domain.create();

// When domain is disabled, no warning will be emitted
makeCallback({ domain: d }, common.mustCall(function() {
assert.strictEqual(latestWarning, null);

d.run(common.mustCall(function() {
// No warning will be emitted when no domain property is applied
makeCallback({}, common.mustCall(function() {
assert.strictEqual(latestWarning, null);

// Warning is emitted when domain property is used and domain is enabled
makeCallback({ domain: d }, common.mustCall(function() {
assert.strictEqual(latestWarning.name, 'DeprecationWarning');
assert.strictEqual(latestWarning.code, 'DEP00XX');
}));
}));
}));
}));