-
Notifications
You must be signed in to change notification settings - Fork 15
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
the async API breaks process.nextTick() within the callback #14
Comments
FYI this is the JavaScript stack trace I get if I print it via ( Inside my callback:
Inside my nextTick callback:
|
node-julia version: |
and if it helps, JuliaLang/julia@fe7203e |
I don't remember doing anything non standard as far as async notification. Just basic uv_async_send, but I do remember there can be only 1 notify delivery for multiple things in uv_async_send so knowing that there's a similar thing that happens in nj maybe something subtle about that. This might prove difficult as inserting logging will alter the eventing behavior. Might be worth attempting with iojs just for perspective and (lack of) reproducibility. BTW just for info, are you using Q or bluebird or something else for the promises wrapping? |
I'm guessing that it may not be enough to notify |
It looks like one way or another you need to call MakeCallback() to actually run the callback and allow nodejs to trigger its It looks like all of the node native libraries use this method. Here's the timers, for example: https://github.com/joyent/node/blob/master/src/timer_wrap.cc#L140 FYI, here's some unit tests showing the callbacks also are not running on the current domain: it('this one works', done => {
const d = domain.create();
d.on('error', () => done());
d.run(() => {
process.nextTick(() => { throw new Error("some error"); });
});
});
it('this one fails', done => {
const d = domain.create();
d.on('error', () => done());
d.run(() => {
julia.eval("2+3", () => { throw new Error("some error"); });
});
}); |
Re: promises. We use So I just use this function to wrap: /**
* Converts a Node.js callback style function to a Promise. This must be in function (err, ...) format.
* @param {Function} func The function to call
* @param {Function} [selector] A selector which takes the arguments from the callback minus the error to produce a single item to yield on next.
* @returns {Function} An async function which when applied, returns a Promise with the callback results (if there are multiple results, then they are supplied as an array)
*/
export function fromNodeCallback(func, selector) {
var newFunc = function (...args) {
return new Promise((resolve, reject) => {
func(...args, (err, ...results) => {
if (err) {
reject(err);
}
else {
let finalResults = results.length > 1 ? results : results[0];
// run the selector if provided
if (selector) {
try {
finalResults = selector(finalResults);
}
catch (e) {
reject(e);
}
}
resolve(finalResults);
}
});
});
};
newFunc.displayName = func.displayName;
return newFunc;
}; Usage: const evalAsync = fromNodeCallback(julia.eval);
const myPromise = evalAsync("2+3"); |
yes I'm using babel + babel runtime + webpack. |
I believe a7cbe3b has addressed this problem, the test case passes, and according to nodejs/nan#284 and this stackoverflow question, it's the right approach. |
Yes this checkin resolves the nextTick issue. The domain test still fails. I'll open a different issue for that. Thanks |
I discovered this issue when I wrapped
eval(expr,cb)
into aPromise
-returning API. Promises execute their callbacks viaprocess.nextTick()
If you call
process.nextTick(foo)
from within the evaluation callback, thenfoo
will not execute until something else happens (such as another timeout expires).See these Mocha tests:
The first test passes.
The second test fails (times out)
The third test (where I added an empty
setTimeout
) passes.It seems like it is related to this issue: nodejs/node-v0.x-archive#7714
I'm guessing your callbacks are somehow bypassing the nodejs event loop and so the event loop does not know to drain the
nextTick
queue until something else happens to wake up the event loop.The text was updated successfully, but these errors were encountered: