-
Notifications
You must be signed in to change notification settings - Fork 78
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
async_wrap: when is callback ready to be called #11
Comments
When the thread is done and when it can get inserted back into the main thread are two different things. If some sync code continues to block past when the async thing is done, there'd be no way for it to enter the suggested "ready" callback.
|
Yeah, that is the But if you have: for (var i = 0; i < 1000; i++) {
fs.open(file[i], 'r', function (err, fd) {
var now = Date.now()
var then = now + 10
while (Date.now() < then);
})
}
setTimeout(function () {
// May first emit after 1000 x 10 ms
}, 20); then it should be possible to emit a |
I have been thinking a lot about this specific issue. A simple alternative
|
Yeah, that would be fine too. I think it would need some kind of async_wrap flag, as getting timestamps can be a bit expensive. |
Don't forget that the function init() {
this._asyncQueue = { init: process.hrtime() };
}
function before() {
this._asyncQueue.before = process.hrtime();
// capture time between init and when before was able to run
}
function after() {
// capture time between before and when after was able to run
} And if all you want to do is get past the synchronous execution stack then use function before() {
var t = process.hrtime();
process.nextTick(function() {
// print time difference
});
} |
Now as far as knowing when the call has actually completed, well you're SOL. Receiving the response from the kernel will be blocked until the sync script is done running, so the only way to get around that would be to accept completed requests from another thread so sync execution wouldn't disrupt the time. But because on Windows the port it tied to the handle it's impossible to do this. Sorry, but unless I'm missing some black magic that's never going to happen. |
@trevnorris Maybe I don't understand the effect of the The To not get misleading numbers, one would need something earlier than If I understand correctly the order of execution for a event loop turn is:
What I'm suggesting is that maybe there is a way to do:
This will not be a perfect approximation, but it will be a better approximation if To get the same effect using exciting API, one could perhaps use a recursive loop of |
@AndreasMadsen I got you, and that's what my second comment above addresses (about being SOL). The completed requests are queued by the kernel and wait patiently for the event loop to retrieve them. Since the event loop is too busy to retrieve these completed requests from the internal queue, it's also too busy to notify you that the request has been completed. You can only be notified of exactly how long a request took if your script is ready to accept the request from the internal queue the moment it's queued. But in that case it'll call the |
@trevnorris Okay, that makes sense. I though the callback queue was maintained by v8. This makes things a bit more difficult :) |
@AndreasMadsen The only way I know of to get around this, to know the exact time of a request, is to perform the request on another thread. Unfortunately that's impossible for a few reasons. If you have any good ideas, let me know, but right now I can't see any way around it. |
closing old AsyncWrap issues, please start a new thread if appropriate |
While developing dprof I came to realize that using
beforeTimestamp (pre hook) - initTimestamp (init hook)
as an async duration estimate is a bit misleading.For example if user create a timeout of
100 ms
and in the meanwhile have a cpu hungry calculation there takes200 ms
. The async operation only takes100 ms
but thebeforeTimestamp - initTimestamp
would indicate200 ms
.A bit more likely, user could do
fs.open
which would finish quickly, but have so many other callbacks there needs calling first that it would take much longer time before thefs.open
callback is called.In both cases it would look like the async operation took much longer than it actually did. The user would ask questions like "why did my timeout take 200 ms, when I set it to 100 ms?" or "why is my filesystem so slow?".
I don't known if it is possible but I think a
asyncReady
event is missing. This would emit when the async operation is done. I'm guessing there is some interrupt causing a push the job queue that one could listen on, but I don't know. Emitting the event immediately would be problematic, as the javascript program would jump in a sync state. So I guessasyncReady
it will just have to be executed right after the current callback is done. This would fix thefs.open
example, but not thesetTimeout
example.The text was updated successfully, but these errors were encountered: