| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 60423f5 commit 9b16e15
9 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -28,7 +28,7 @@ | |||
| 28 | 28 | ||
| 29 | 29 | const util = require('util'); | |
| 30 | 30 | const EventEmitter = require('events'); | |
| 31 | - const { inherits } = util; | ||
| 31 | + const { createHook } = require('async_hooks'); | ||
| 32 | 32 | ||
| 33 | 33 | // communicate with events module, but don't require that | |
| 34 | 34 | // module to have to load this one, since this module has | |
@@ -48,13 +48,54 @@ Object.defineProperty(process, 'domain', { | |||
| 48 | 48 | } | |
| 49 | 49 | }); | |
| 50 | 50 | ||
| 51 | + const pairing = new Map(); | ||
| 52 | + const asyncHook = createHook({ | ||
| 53 | + init(asyncId, type, triggerAsyncId, resource) { | ||
| 54 | + if (process.domain !== null && process.domain !== undefined) { | ||
| 55 | + // if this operation is created while in a domain, let's mark it | ||
| 56 | + pairing.set(asyncId, process.domain); | ||
| 57 | + resource.domain = process.domain; | ||
| 58 | + if (resource.promise !== undefined && | ||
| 59 | + resource.promise instanceof Promise) { | ||
| 60 | + // resource.promise instanceof Promise make sure that the | ||
| 61 | + // promise comes from the same context | ||
| 62 | + // see https://github.com/nodejs/node/issues/15673 | ||
| 63 | + resource.promise.domain = process.domain; | ||
| 64 | + } | ||
| 65 | + } | ||
| 66 | + }, | ||
| 67 | + before(asyncId) { | ||
| 68 | + const current = pairing.get(asyncId); | ||
| 69 | + if (current !== undefined) { // enter domain for this cb | ||
| 70 | + current.enter(); | ||
| 71 | + } | ||
| 72 | + }, | ||
| 73 | + after(asyncId) { | ||
| 74 | + const current = pairing.get(asyncId); | ||
| 75 | + if (current !== undefined) { // exit domain for this cb | ||
| 76 | + current.exit(); | ||
| 77 | + } | ||
| 78 | + }, | ||
| 79 | + destroy(asyncId) { | ||
| 80 | + pairing.delete(asyncId); // cleaning up | ||
| 81 | + } | ||
| 82 | + }); | ||
| 83 | + | ||
| 51 | 84 | // It's possible to enter one domain while already inside | |
| 52 | 85 | // another one. The stack is each entered domain. | |
| 53 | 86 | const stack = []; | |
| 54 | 87 | exports._stack = stack; | |
| 88 | + process._setupDomainUse(stack); | ||
| 89 | + | ||
| 90 | + class Domain extends EventEmitter { | ||
| 55 | 91 | ||
| 56 | - // let the process know we're using domains | ||
| 57 | - const _domain_flag = process._setupDomainUse(_domain, stack); | ||
| 92 | + constructor() { | ||
| 93 | + super(); | ||
| 94 | + | ||
| 95 | + this.members = []; | ||
| 96 | + asyncHook.enable(); | ||
| 97 | + } | ||
| 98 | + } | ||
| 58 | 99 | ||
| 59 | 100 | exports.Domain = Domain; | |
| 60 | 101 | ||
@@ -64,19 +105,8 @@ exports.create = exports.createDomain = function() { | |||
| 64 | 105 | ||
| 65 | 106 | // the active domain is always the one that we're currently in. | |
| 66 | 107 | exports.active = null; | |
| 67 | - | ||
| 68 | - | ||
| 69 | - inherits(Domain, EventEmitter); | ||
| 70 | - | ||
| 71 | - function Domain() { | ||
| 72 | - EventEmitter.call(this); | ||
| 73 | - | ||
| 74 | - this.members = []; | ||
| 75 | - } | ||
| 76 | - | ||
| 77 | 108 | Domain.prototype.members = undefined; | |
| 78 | 109 | ||
| 79 | - | ||
| 80 | 110 | // Called by process._fatalException in case an error was thrown. | |
| 81 | 111 | Domain.prototype._errorHandler = function _errorHandler(er) { | |
| 82 | 112 | var caught = false; | |
@@ -155,7 +185,6 @@ Domain.prototype.enter = function() { | |||
| 155 | 185 | // to push it onto the stack so that we can pop it later. | |
| 156 | 186 | exports.active = process.domain = this; | |
| 157 | 187 | stack.push(this); | |
| 158 | - _domain_flag[0] = stack.length; | ||
| 159 | 188 | }; | |
| 160 | 189 | ||
| 161 | 190 | ||
@@ -166,7 +195,6 @@ Domain.prototype.exit = function() { | |||
| 166 | 195 | ||
| 167 | 196 | // exit all domains until this one. | |
| 168 | 197 | stack.splice(index); | |
| 169 | - _domain_flag[0] = stack.length; | ||
| 170 | 198 | ||
| 171 | 199 | exports.active = stack[stack.length - 1]; | |
| 172 | 200 | process.domain = exports.active; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -73,7 +73,6 @@ function setupNextTick() { | |||
| 73 | 73 | process.nextTick = nextTick; | |
| 74 | 74 | // Needs to be accessible from beyond this scope. | |
| 75 | 75 | process._tickCallback = _tickCallback; | |
| 76 | - process._tickDomainCallback = _tickDomainCallback; | ||
| 77 | 76 | ||
| 78 | 77 | // Set the nextTick() function for internal usage. | |
| 79 | 78 | exports.nextTick = internalNextTick; | |
@@ -190,46 +189,6 @@ function setupNextTick() { | |||
| 190 | 189 | } while (tickInfo[kLength] !== 0); | |
| 191 | 190 | } | |
| 192 | 191 | ||
| 193 | - function _tickDomainCallback() { | ||
| 194 | - do { | ||
| 195 | - while (tickInfo[kIndex] < tickInfo[kLength]) { | ||
| 196 | - ++tickInfo[kIndex]; | ||
| 197 | - const tock = nextTickQueue.shift(); | ||
| 198 | - const callback = tock.callback; | ||
| 199 | - const domain = tock.domain; | ||
| 200 | - const args = tock.args; | ||
| 201 | - if (domain) | ||
| 202 | - domain.enter(); | ||
| 203 | - | ||
| 204 | - // CHECK(Number.isSafeInteger(tock[async_id_symbol])) | ||
| 205 | - // CHECK(tock[async_id_symbol] > 0) | ||
| 206 | - // CHECK(Number.isSafeInteger(tock[trigger_async_id_symbol])) | ||
| 207 | - // CHECK(tock[trigger_async_id_symbol] > 0) | ||
| 208 | - | ||
| 209 | - emitBefore(tock[async_id_symbol], tock[trigger_async_id_symbol]); | ||
| 210 | - // TODO(trevnorris): See comment in _tickCallback() as to why this | ||
| 211 | - // isn't a good solution. | ||
| 212 | - if (async_hook_fields[kDestroy] > 0) | ||
| 213 | - emitDestroy(tock[async_id_symbol]); | ||
| 214 | - | ||
| 215 | - // Using separate callback execution functions allows direct | ||
| 216 | - // callback invocation with small numbers of arguments to avoid the | ||
| 217 | - // performance hit associated with using `fn.apply()` | ||
| 218 | - _combinedTickCallback(args, callback); | ||
| 219 | - | ||
| 220 | - emitAfter(tock[async_id_symbol]); | ||
| 221 | - | ||
| 222 | - if (kMaxCallbacksPerLoop < tickInfo[kIndex]) | ||
| 223 | - tickDone(); | ||
| 224 | - if (domain) | ||
| 225 | - domain.exit(); | ||
| 226 | - } | ||
| 227 | - tickDone(); | ||
| 228 | - _runMicrotasks(); | ||
| 229 | - emitPendingUnhandledRejections(); | ||
| 230 | - } while (tickInfo[kLength] !== 0); | ||
| 231 | - } | ||
| 232 | - | ||
| 233 | 192 | class TickObject { | |
| 234 | 193 | constructor(callback, args, asyncId, triggerAsyncId) { | |
| 235 | 194 | this.callback = callback; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -596,12 +596,6 @@ class QueryWrap : public AsyncWrap { | |||
| 596 | 596 | QueryWrap(ChannelWrap* channel, Local<Object> req_wrap_obj) | |
| 597 | 597 | : AsyncWrap(channel->env(), req_wrap_obj, AsyncWrap::PROVIDER_QUERYWRAP), | |
| 598 | 598 | channel_(channel) { | |
| 599 | - if (env()->in_domain()) { | ||
| 600 | - req_wrap_obj->Set(env()->domain_string(), | ||
| 601 | - env()->domain_array()->Get(env()->context(), 0) | ||
| 602 | - .ToLocalChecked()); | ||
| 603 | - } | ||
| 604 | - | ||
| 605 | 599 | Wrap(req_wrap_obj, this); | |
| 606 | 600 | ||
| 607 | 601 | // Make sure the channel object stays alive during the query lifetime. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -200,22 +200,6 @@ inline bool Environment::AsyncCallbackScope::in_makecallback() const { | |||
| 200 | 200 | return env_->makecallback_cntr_ > 1; | |
| 201 | 201 | } | |
| 202 | 202 | ||
| 203 | - inline Environment::DomainFlag::DomainFlag() { | ||
| 204 | - for (int i = 0; i < kFieldsCount; ++i) fields_[i] = 0; | ||
| 205 | - } | ||
| 206 | - | ||
| 207 | - inline uint32_t* Environment::DomainFlag::fields() { | ||
| 208 | - return fields_; | ||
| 209 | - } | ||
| 210 | - | ||
| 211 | - inline int Environment::DomainFlag::fields_count() const { | ||
| 212 | - return kFieldsCount; | ||
| 213 | - } | ||
| 214 | - | ||
| 215 | - inline uint32_t Environment::DomainFlag::count() const { | ||
| 216 | - return fields_[kCount]; | ||
| 217 | - } | ||
| 218 | - | ||
| 219 | 203 | inline Environment::TickInfo::TickInfo() { | |
| 220 | 204 | for (int i = 0; i < kFieldsCount; ++i) | |
| 221 | 205 | fields_[i] = 0; | |
@@ -347,12 +331,6 @@ inline v8::Isolate* Environment::isolate() const { | |||
| 347 | 331 | return isolate_; | |
| 348 | 332 | } | |
| 349 | 333 | ||
| 350 | - inline bool Environment::in_domain() const { | ||
| 351 | - // The const_cast is okay, it doesn't violate conceptual const-ness. | ||
| 352 | - return using_domains() && | ||
| 353 | - const_cast<Environment*>(this)->domain_flag()->count() > 0; | ||
| 354 | - } | ||
| 355 | - | ||
| 356 | 334 | inline Environment* Environment::from_immediate_check_handle( | |
| 357 | 335 | uv_check_t* handle) { | |
| 358 | 336 | return ContainerOf(&Environment::immediate_check_handle_, handle); | |
@@ -393,10 +371,6 @@ inline Environment::AsyncHooks* Environment::async_hooks() { | |||
| 393 | 371 | return &async_hooks_; | |
| 394 | 372 | } | |
| 395 | 373 | ||
| 396 | - inline Environment::DomainFlag* Environment::domain_flag() { | ||
| 397 | - return &domain_flag_; | ||
| 398 | - } | ||
| 399 | - | ||
| 400 | 374 | inline Environment::TickInfo* Environment::tick_info() { | |
| 401 | 375 | return &tick_info_; | |
| 402 | 376 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -309,7 +309,6 @@ class ModuleWrap; | |||
| 309 | 309 | V(internal_binding_cache_object, v8::Object) \ | |
| 310 | 310 | V(buffer_prototype_object, v8::Object) \ | |
| 311 | 311 | V(context, v8::Context) \ | |
| 312 | - V(domain_array, v8::Array) \ | ||
| 313 | 312 | V(domains_stack_array, v8::Array) \ | |
| 314 | 313 | V(http2ping_constructor_template, v8::ObjectTemplate) \ | |
| 315 | 314 | V(http2stream_constructor_template, v8::ObjectTemplate) \ | |
@@ -474,26 +473,6 @@ class Environment { | |||
| 474 | 473 | DISALLOW_COPY_AND_ASSIGN(AsyncCallbackScope); | |
| 475 | 474 | }; | |
| 476 | 475 | ||
| 477 | - class DomainFlag { | ||
| 478 | - public: | ||
| 479 | - inline uint32_t* fields(); | ||
| 480 | - inline int fields_count() const; | ||
| 481 | - inline uint32_t count() const; | ||
| 482 | - | ||
| 483 | - private: | ||
| 484 | - friend class Environment; // So we can call the constructor. | ||
| 485 | - inline DomainFlag(); | ||
| 486 | - | ||
| 487 | - enum Fields { | ||
| 488 | - kCount, | ||
| 489 | - kFieldsCount | ||
| 490 | - }; | ||
| 491 | - | ||
| 492 | - uint32_t fields_[kFieldsCount]; | ||
| 493 | - | ||
| 494 | - DISALLOW_COPY_AND_ASSIGN(DomainFlag); | ||
| 495 | - }; | ||
| 496 | - | ||
| 497 | 476 | class TickInfo { | |
| 498 | 477 | public: | |
| 499 | 478 | inline uint32_t* fields(); | |
@@ -562,7 +541,6 @@ class Environment { | |||
| 562 | 541 | ||
| 563 | 542 | inline v8::Isolate* isolate() const; | |
| 564 | 543 | inline uv_loop_t* event_loop() const; | |
| 565 | - inline bool in_domain() const; | ||
| 566 | 544 | inline uint32_t watched_providers() const; | |
| 567 | 545 | ||
| 568 | 546 | static inline Environment* from_immediate_check_handle(uv_check_t* handle); | |
@@ -579,7 +557,6 @@ class Environment { | |||
| 579 | 557 | inline void FinishHandleCleanup(uv_handle_t* handle); | |
| 580 | 558 | ||
| 581 | 559 | inline AsyncHooks* async_hooks(); | |
| 582 | - inline DomainFlag* domain_flag(); | ||
| 583 | 560 | inline TickInfo* tick_info(); | |
| 584 | 561 | inline uint64_t timer_base() const; | |
| 585 | 562 | ||
@@ -709,7 +686,6 @@ class Environment { | |||
| 709 | 686 | uv_check_t idle_check_handle_; | |
| 710 | 687 | ||
| 711 | 688 | AsyncHooks async_hooks_; | |
| 712 | - DomainFlag domain_flag_; | ||
| 713 | 689 | TickInfo tick_info_; | |
| 714 | 690 | const uint64_t timer_base_; | |
| 715 | 691 | bool using_domains_; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -150,7 +150,6 @@ using v8::Number; | |||
| 150 | 150 | using v8::Object; | |
| 151 | 151 | using v8::ObjectTemplate; | |
| 152 | 152 | using v8::Promise; | |
| 153 | - using v8::PromiseHookType; | ||
| 154 | 153 | using v8::PromiseRejectMessage; | |
| 155 | 154 | using v8::PropertyCallbackInfo; | |
| 156 | 155 | using v8::ScriptOrigin; | |
@@ -1178,7 +1177,6 @@ bool ShouldAbortOnUncaughtException(Isolate* isolate) { | |||
| 1178 | 1177 | return isEmittingTopLevelDomainError || !DomainsStackHasErrorHandler(env); | |
| 1179 | 1178 | } | |
| 1180 | 1179 | ||
| 1181 | - | ||
| 1182 | 1180 | Local<Value> GetDomainProperty(Environment* env, Local<Object> object) { | |
| 1183 | 1181 | Local<Value> domain_v = | |
| 1184 | 1182 | object->GetPrivate(env->context(), env->domain_private_symbol()) | |
@@ -1219,36 +1217,6 @@ void DomainExit(Environment* env, v8::Local<v8::Object> object) { | |||
| 1219 | 1217 | } | |
| 1220 | 1218 | } | |
| 1221 | 1219 | ||
| 1222 | - | ||
| 1223 | - void DomainPromiseHook(PromiseHookType type, | ||
| 1224 | - Local<Promise> promise, | ||
| 1225 | - Local<Value> parent, | ||
| 1226 | - void* arg) { | ||
| 1227 | - Environment* env = static_cast<Environment*>(arg); | ||
| 1228 | - Local<Context> context = env->context(); | ||
| 1229 | - | ||
| 1230 | - if (type == PromiseHookType::kInit && env->in_domain()) { | ||
| 1231 | - Local<Value> domain_obj = | ||
| 1232 | - env->domain_array()->Get(context, 0).ToLocalChecked(); | ||
| 1233 | - if (promise->CreationContext() == context) { | ||
| 1234 | - promise->Set(context, env->domain_string(), domain_obj).FromJust(); | ||
| 1235 | - } else { | ||
| 1236 | - // Do not expose object from another context publicly in promises created | ||
| 1237 | - // in non-main contexts. | ||
| 1238 | - promise->SetPrivate(context, env->domain_private_symbol(), domain_obj) | ||
| 1239 | - .FromJust(); | ||
| 1240 | - } | ||
| 1241 | - return; | ||
| 1242 | - } | ||
| 1243 | - | ||
| 1244 | - if (type == PromiseHookType::kBefore) { | ||
| 1245 | - DomainEnter(env, promise); | ||
| 1246 | - } else if (type == PromiseHookType::kAfter) { | ||
| 1247 | - DomainExit(env, promise); | ||
| 1248 | - } | ||
| 1249 | - } | ||
| 1250 | - | ||
| 1251 | - | ||
| 1252 | 1220 | void SetupDomainUse(const FunctionCallbackInfo<Value>& args) { | |
| 1253 | 1221 | Environment* env = Environment::GetCurrent(args); | |
| 1254 | 1222 | ||
@@ -1259,38 +1227,13 @@ void SetupDomainUse(const FunctionCallbackInfo<Value>& args) { | |||
| 1259 | 1227 | HandleScope scope(env->isolate()); | |
| 1260 | 1228 | Local<Object> process_object = env->process_object(); | |
| 1261 | 1229 | ||
| 1262 | - Local<String> tick_callback_function_key = env->tick_domain_cb_string(); | ||
| 1263 | - Local<Function> tick_callback_function = | ||
| 1264 | - process_object->Get(tick_callback_function_key).As<Function>(); | ||
| 1265 | - | ||
| 1266 | - if (!tick_callback_function->IsFunction()) { | ||
| 1267 | - fprintf(stderr, "process._tickDomainCallback assigned to non-function\n"); | ||
| 1268 | - ABORT(); | ||
| 1269 | - } | ||
| 1270 | - | ||
| 1271 | - process_object->Set(env->tick_callback_string(), tick_callback_function); | ||
| 1272 | - env->set_tick_callback_function(tick_callback_function); | ||
| 1273 | - | ||
| 1274 | 1230 | CHECK(args[0]->IsArray()); | |
| 1275 | - env->set_domain_array(args[0].As<Array>()); | ||
| 1276 | - | ||
| 1277 | - CHECK(args[1]->IsArray()); | ||
| 1278 | - env->set_domains_stack_array(args[1].As<Array>()); | ||
| 1231 | + env->set_domains_stack_array(args[0].As<Array>()); | ||
| 1279 | 1232 | ||
| 1280 | 1233 | // Do a little housekeeping. | |
| 1281 | 1234 | env->process_object()->Delete( | |
| 1282 | 1235 | env->context(), | |
| 1283 | 1236 | FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupDomainUse")).FromJust(); | |
| 1284 | - | ||
| 1285 | - uint32_t* const fields = env->domain_flag()->fields(); | ||
| 1286 | - uint32_t const fields_count = env->domain_flag()->fields_count(); | ||
| 1287 | - | ||
| 1288 | - Local<ArrayBuffer> array_buffer = | ||
| 1289 | - ArrayBuffer::New(env->isolate(), fields, sizeof(*fields) * fields_count); | ||
| 1290 | - | ||
| 1291 | - env->AddPromiseHook(DomainPromiseHook, static_cast<void*>(env)); | ||
| 1292 | - | ||
| 1293 | - args.GetReturnValue().Set(Uint32Array::New(array_buffer, 0, fields_count)); | ||
| 1294 | 1237 | } | |
| 1295 | 1238 | ||
| 1296 | 1239 | ||
@@ -1414,7 +1357,8 @@ InternalCallbackScope::InternalCallbackScope(Environment* env, | |||
| 1414 | 1357 | // If you hit this assertion, you forgot to enter the v8::Context first. | |
| 1415 | 1358 | CHECK_EQ(Environment::GetCurrent(env->isolate()), env); | |
| 1416 | 1359 | ||
| 1417 | - if (env->using_domains() && !object_.IsEmpty()) { | ||
| 1360 | + if (asyncContext.async_id == 0 && env->using_domains() && | ||
| 1361 | + !object_.IsEmpty()) { | ||
| 1418 | 1362 | DomainEnter(env, object_); | |
| 1419 | 1363 | } | |
| 1420 | 1364 | ||
@@ -1447,7 +1391,8 @@ void InternalCallbackScope::Close() { | |||
| 1447 | 1391 | AsyncWrap::EmitAfter(env_, async_context_.async_id); | |
| 1448 | 1392 | } | |
| 1449 | 1393 | ||
| 1450 | - if (env_->using_domains() && !object_.IsEmpty()) { | ||
| 1394 | + if (async_context_.async_id == 0 && env_->using_domains() && | ||
| 1395 | + !object_.IsEmpty()) { | ||
| 1451 | 1396 | DomainExit(env_, object_); | |
| 1452 | 1397 | } | |
| 1453 | 1398 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments