Hidden threads in Javascript/Node that never execute user code: is it possible, and if so could it lead to an arcane possibility for a race condition?

℡╲_俬逩灬. 提交于 2019-11-27 09:36:35

No, this cannot happen.

Yes, there are indeed "hidden" background threads that do the work for asychronous methods, but those don't call callbacks. All execution of javascript does happen on the same thread, synchronously, sequentially. That data event callback will always be executed asynchronously, that is, after the current script/function ran to completion.

While there could indeed already arrive packets from the network before the callback is created and attached to the event emitter, the callback that listens for packets on the lowest level is always created before the request is sent - it is an argument to the native "makeRequest" method, and is available to be called right from the beginning. So when a packet does arrive before the current script (still being occupied by constructing event emitters and attaching handlers) has finished, this event is queued up, and the callback will only be executed after the event loop is ready - on the next turn. By then, the data event callback is certainly created and attached.

nodejs Javsacript execution is single threaded and event driven. That means that everything runs through an event queue. A thread of Javascript execution runs until it's done and then the system checks the event queue to see if there's anything else to do (timers waiting to fire, async callbacks waiting to be called, etc...).

nodejs does use some internal threads in some of its implementation (such as file I/O), but it is my understanding that it does not use threads in networking. But, it's immaterial whether there are some internal threads or not because all communication between sub-systems like networking and the main nodejs JS thread is via the event queue.

A nodejs thread of execution is never interrupted to do something else. It finishes and runs to completion, then the JS engine checks the event queue to see if there's something else waiting to be executed.

When there's incoming data available on socket, an event is placed in the event queue. The current nodejs Javascript that is executing finishes doing what it's doing, then the JS engine sees there's an event in the event queue and fires that event. If there's a function callback or event handler associated with that event (there usually is), then that gets called to execute the event.

If there's a mishap in the internals of some infrastructure such as networking, then all that happens to the nodejs code is that some networking event just doesn't occur. The nodejs code has its event handlers in place and just doesn't receive the event they are waiting for until the infrastructure gets unwedged and creates the event. This doesn't create any sort of hang in the nodejs code.

So, in your update:

From comments & answers: I now have clarified my question. The 'arcane scenario' would require that there is a HIDDEN thread (which therefore CANNOT execute any USER code, including CALLBACKS) that constructs the request, sends it over the network, and receives the response - WITHOUT having any callbacks to trigger, including the 'data' callback - and stops short just at the point that the 'response' callback is ready to be called, waiting for the (single) visible JS thread to wake up.

The nodejs thread runs to completion, then the JS engine waits for a new event to occur (e.g. get put in the event queue). When that event occurs, the JS engine runs the code that corresponds to that event (event handlers, callbacks, etc...). You make it sound like the single visible JS thread is asleep waiting to wake up and it can get stuck there because some other sub-system gets hung. That is not the case. The only thing that can happen is that some event that the single JS thread has an event handler for just never occurs. This would be no different than a situation where you send a message to a server and you have an event handler to see a response, but the server never sends the response. Your nodejs code continues processing other events (timers, other networking, other I/O), but this particular event just never occurs because the other server just never sent the data that would trigger that event. Nothing hangs.

This is "evented I/O" which is how nodejs describes itself.

There’s only one thread involved in Node.js; an event loop is used to process tasks that run asynchronously, and nothing queued will ever interrupt anything already running. So no, there is no race condition there.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!