Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Patch captureStackTrace/prepareStackTrace to ZoneAwareError, patch process.nextTick, fix removeAllListeners bug #516

Merged
merged 28 commits into from
Dec 5, 2016

Conversation

JiaLiPassion
Copy link
Collaborator

@JiaLiPassion JiaLiPassion commented Nov 23, 2016

  1. ZoneAwareError didn't add captureStackTrace method, so it will failed when user call Error.captureStackTrace. for example issue 0.7.1 Breaking Error #515

  2. ZoneAwareError didn't add Error.prepareStackTrace callback, so if user add prepareStackTrace callback to Error, the callback will not be executed. for example issue 0.7.1 Breaking Error #515

https://github.com/v8/v8/wiki/Stack-Trace-API

  1. patch process.nextTick with zone.scheduleMicroTask, so process.nextTick can be in zone, and can be handled by ZoneDelegate task related callback(onScheduleTask/onInvokeTask) Patch process.nextTick() #505

  2. modify a typo, FrameType.trasition->FrameType.transition

  3. fix EventEmitter.removeAllListeners bug Incompatabile with nodejs 6.9.1: makeZoneAwareRemoveAllListeners addes 'undefined' arguments to real removeAllListeners calls #518, when call EventEmitter.removeAllListeners without eventName, should remove all eventListener, and add some test cases for EventEmitter.removeListener/newListener.

  4. update fetch to 2.0.1 in package.json

@@ -30,6 +30,13 @@ if (shouldPatchGlobalTimers) {
patchTimer(_global, set, clear, 'Immediate');
}

// patch process.nextTick
var nativeNextTick = process.nextTick;
Copy link
Contributor

@Brooooooklyn Brooooooklyn Nov 23, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe use const better

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, you are right, thank you.

@JiaLiPassion JiaLiPassion changed the title Restore captureStackTrace method to ZoneAwareError and patch process.nextTick Patch captureStackTrace/prepareStackTrace to ZoneAwareError and patch process.nextTick Nov 23, 2016
@JiaLiPassion JiaLiPassion changed the title Patch captureStackTrace/prepareStackTrace to ZoneAwareError and patch process.nextTick Patch captureStackTrace/prepareStackTrace to ZoneAwareError, patch process.nextTick, fix removeAllListeners bug Nov 24, 2016
Copy link

@KrauseStefan KrauseStefan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've looked through the changes, keep in mind that I'm not directly attached to the project so take the feedback for what it is, I do however believe that a few changes are needed before a merge.

// remove all listeners without eventName
target[EVENT_TASKS] = [];
target[symbol]();
return;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The real removeAllListeners(...)
return this
This wrapper should do the same
https://github.com/nodejs/node/blob/master/lib/events.js#L404

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In typescript I believe you probably want to use either let or const as far as I can tell all except the logic in the loop can use const.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, I will change the var to const.
and about the return this part, it has been handled by https://github.com/angular/zone.js/blob/master/lib/node/events.ts#L14

var eventName = args[0];
var useCapturing = args[1] || defaultUseCapturing;
var target = self || _global;
var eventTasks = findAllExistingRegisteredTasks(target, eventName, useCapturing, true);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When all all listeners are removed shouldn't all the eventTasks also be chanceled?
I believe we need to look into how to use findAllExistingRegisteredTasks to get and cancel all eventTasks.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the cancelTask will just call the original EventEmitter.removeListener, I think we don't need to cancel it, because when we call targetsymbol https://github.com/angular/zone.js/pull/516/files#diff-f5e084bcb7c43d977d56c3b791bbca2dR287, the EventEmitter.removeAllListeners will do it for us.

and the cancelTask call here is also not necessary either I think, https://github.com/angular/zone.js/blob/master/lib/common/utils.ts#L290

@nakedcity
Copy link

nakedcity commented Nov 25, 2016

Tested it, seems to fix the issue. When are you planning to merge this?

args[0] = function() {
task.invoke.apply(this, arguments);
};
setNative.apply(process, args);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be setNative.apply(self, args) using the self variable coming from patchMethod? Not actually a problem since nextTick appears to bind callbacks to global, but still

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, we can pass the self form patchMethod to scheduleTask, but here we know it is process , so we can just use process directly, just like patch timer.https://github.com/angular/zone.js/blob/master/lib/common/timers.ts#L30

Copy link
Contributor

@sjelin sjelin Nov 30, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we know it's process?

var nextTick = process.nextTick;
nextTick.call(myObject, function() {
  console.log(this); // If `nextTick` passed its context object directly to
                     // its callback, this would be `myObject`.  However, 
                     // with the zone.js patch, this would be `process`
});

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I edited my code in the above comment, since it used to make no sense)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but I can't imagine when we need to call like nextTick.call(myObject, ...), in my understanding we should always call nextTick.call(process, ...)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also don't think there's ever a good reason to call nextTick with a different context, especially since with the current implementation (and probably all past/future implementations) it would be useless anyway. But it is allowable to use a different context, and so this could be a problem in the future. With setTimeout the DOM spec requires you to call it on an object of type Window or WorkerGlobalScope (i.e. the global scope)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway, I'd prefer to see it the other way, but it honestly doesn't matter

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it is allowable to use a different context, and so this could be a problem in the future. With setTimeout the DOM spec requires you to call it on an object of type Window or WorkerGlobalScope (i.e. the global scope)

I didn't know such kind of usage, thank you for the information. in this PR, I'll just keep it this way just to make the coding style be the same with patchTimer. Thanks again.

@@ -83,3 +85,28 @@ if (httpClient && httpClient.ClientRequest) {
}
};
}

function patchNextTick() {
let setNative = null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems weird to use this local variable instead of moving scheduleTask inside of patchMethod, but I guess you're trying to limit nested closures?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I agree, I just keep the coding style to be the same with timer patch, https://github.com/angular/zone.js/blob/master/lib/common/timers.ts#L17

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants