Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 1676810

Browse files
ofrobotsxzyfer
authored andcommittedApr 4, 2018
fix: propagate async context
This is an alternative to some of the fixes in [1]. Starting with Nan 2.9.0, we have the ability to propagate async context across async hops. Certain variants of Nan::Callback::Call are now deprecated to encourage use of the context presevering alternatives. Certain variants of Node's MakeCallback that were used internally are going to be deprecated in Node 10. Summary is that one should use Nan::Call for sync calls, and Nan::Callback::Call for async. The latter expects an async resource corresponding to the async operation to be provided at the call time. This patch fixes things up so that 1) node-sass isn't using any deprecated APIs, and 2) properly propagates async context for async callbacks by creating async resources in the appropriate places. [1]: #2295
1 parent 909f694 commit 1676810

4 files changed

+23
-6
lines changed
 

‎src/binding.cpp

+14-3
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,16 @@ int GetResult(sass_context_wrapper* ctx_w, Sass_Context* ctx, bool is_sync = fal
227227
return status;
228228
}
229229

230+
void PerformCall(sass_context_wrapper* ctx_w, Nan::Callback* callback, int argc, v8::Local<v8::Value> argv[]) {
231+
if (ctx_w->is_sync) {
232+
Nan::Call(*callback, argc, argv);
233+
} else {
234+
callback->Call(argc, argv, ctx_w->async_resource);
235+
}
236+
}
237+
230238
void MakeCallback(uv_work_t* req) {
231239
Nan::HandleScope scope;
232-
Nan::AsyncResource async("sass:MakeCallback");
233240

234241
Nan::TryCatch try_catch;
235242
sass_context_wrapper* ctx_w = static_cast<sass_context_wrapper*>(req->data);
@@ -246,15 +253,15 @@ void MakeCallback(uv_work_t* req) {
246253

247254
if (status == 0 && ctx_w->success_callback) {
248255
// if no error, do callback(null, result)
249-
ctx_w->success_callback->Call(0, 0, &async);
256+
PerformCall(ctx_w, ctx_w->success_callback, 0, 0);
250257
}
251258
else if (ctx_w->error_callback) {
252259
// if error, do callback(error)
253260
const char* err = sass_context_get_error_json(ctx);
254261
v8::Local<v8::Value> argv[] = {
255262
Nan::New<v8::String>(err).ToLocalChecked()
256263
};
257-
ctx_w->error_callback->Call(1, argv, &async);
264+
PerformCall(ctx_w, ctx_w->error_callback, 1, argv);
258265
}
259266
if (try_catch.HasCaught()) {
260267
Nan::FatalException(try_catch);
@@ -270,6 +277,8 @@ NAN_METHOD(render) {
270277
struct Sass_Data_Context* dctx = sass_make_data_context(source_string);
271278
sass_context_wrapper* ctx_w = sass_make_context_wrapper();
272279

280+
ctx_w->async_resource = new Nan::AsyncResource("node-sass:sass_context_wrapper:render");
281+
273282
if (ExtractOptions(options, dctx, ctx_w, false, false) >= 0) {
274283

275284
int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback);
@@ -304,6 +313,8 @@ NAN_METHOD(render_file) {
304313
struct Sass_File_Context* fctx = sass_make_file_context(input_path);
305314
sass_context_wrapper* ctx_w = sass_make_context_wrapper();
306315

316+
ctx_w->async_resource = new Nan::AsyncResource("node-sass:sass_context_wrapper:render_file");
317+
307318
if (ExtractOptions(options, fctx, ctx_w, true, false) >= 0) {
308319

309320
int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback);

‎src/callback_bridge.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class CallbackBridge {
4040
virtual std::vector<v8::Local<v8::Value>> pre_process_args(std::vector<L>) const =0;
4141

4242
Nan::Callback* callback;
43+
Nan::AsyncResource* async_resource;
4344
bool is_sync;
4445

4546
uv_mutex_t cv_mutex;
@@ -66,6 +67,7 @@ CallbackBridge<T, L>::CallbackBridge(v8::Local<v8::Function> callback, bool is_s
6667
this->async = new uv_async_t;
6768
this->async->data = (void*) this;
6869
uv_async_init(uv_default_loop(), this->async, (uv_async_cb) dispatched_async_uv_callback);
70+
this->async_resource = new Nan::AsyncResource("node-sass:CallbackBridge");
6971
}
7072

7173
v8::Local<v8::Function> func = CallbackBridge<T, L>::get_wrapper_constructor().ToLocalChecked();
@@ -82,6 +84,7 @@ CallbackBridge<T, L>::~CallbackBridge() {
8284

8385
if (!is_sync) {
8486
uv_close((uv_handle_t*)this->async, &async_gone);
87+
delete this->async_resource;
8588
}
8689
}
8790

@@ -107,7 +110,7 @@ T CallbackBridge<T, L>::operator()(std::vector<void*> argv) {
107110
argv_v8.push_back(Nan::New(wrapper));
108111

109112
return this->post_process_return_value(
110-
Nan::Call(*callback, argv_v8.size(), &argv_v8[0]).ToLocalChecked()
113+
Nan::Call(*this->callback, argv_v8.size(), &argv_v8[0]).ToLocalChecked()
111114
);
112115
} else {
113116
/*
@@ -151,7 +154,6 @@ void CallbackBridge<T, L>::dispatched_async_uv_callback(uv_async_t *req) {
151154
* post_process_args().
152155
*/
153156
Nan::HandleScope scope;
154-
Nan::AsyncResource async("sass:CallbackBridge");
155157
Nan::TryCatch try_catch;
156158

157159
std::vector<v8::Local<v8::Value>> argv_v8 = bridge->pre_process_args(bridge->argv);
@@ -160,7 +162,7 @@ void CallbackBridge<T, L>::dispatched_async_uv_callback(uv_async_t *req) {
160162
}
161163
argv_v8.push_back(Nan::New(bridge->wrapper));
162164

163-
bridge->callback->Call(argv_v8.size(), &argv_v8[0], &async);
165+
bridge->callback->Call(argv_v8.size(), &argv_v8[0], bridge->async_resource);
164166

165167
if (try_catch.HasCaught()) {
166168
Nan::FatalException(try_catch);

‎src/sass_context_wrapper.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ extern "C" {
3333
else if (ctx_w->fctx) {
3434
sass_delete_file_context(ctx_w->fctx);
3535
}
36+
if (ctx_w->async_resource) {
37+
delete ctx_w->async_resource;
38+
}
3639

3740
delete ctx_w->error_callback;
3841
delete ctx_w->success_callback;

‎src/sass_context_wrapper.h

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ extern "C" {
3939

4040
// v8 and nan related
4141
Nan::Persistent<v8::Object> result;
42+
Nan::AsyncResource* async_resource;
4243
Nan::Callback* error_callback;
4344
Nan::Callback* success_callback;
4445

0 commit comments

Comments
 (0)
This repository has been archived.