I am building a calculator that makes lots of XHR calls and was wondering if placing these in a web worker, synchronously, would still lock the browser? It's my understanding these are handled in a different thread and shouldn't.
(I've built the algorithm asynchronously before, it's just very hard code to maintain and I only am looking to this option to keep the code more maintainable. I understand why it shouldn't be synchronous outside of a web worker.)
Without another processor available, it won't be as bad as it would be without Web Workers (because the OS can round-robin schedule the two threads to run interleaved even one on processor).
And with another processor available, the OS would ideally schedule it to run on that thread, and they would both run at full speed.
Related
I have been learning Node.js, but I have one question for which I cannot find answer anywhere. Here is what I get about Node.js=>
It is single-threaded in its architecture and uses CPU utilization efficiently due to its asynchronous non-blocking event-based looping.
How it executes these asynchronous requests is with the help of in-built library libuv, which uses threads(4 threads by default) in its internal thread pool. All these is kept away from "main" master thread which node.js uses. So we do not have to worry about that.
However, here is what my question - Suppose there are 100 asynchronous requests (let's say files) at once. Since the no. of threads libuv uses is limited, how exactly can node.js handle these 100 asynchronous requests at a time? It should ideally have 100 threads to handle these 100 asynchronous requests to respond the data back to the event queue quickly. How exactly is this faster than multi-threaded process?
How exactly is this faster than multi-threaded process?
The simple answer is, sometimes it isn't. No platform/language/compiler is best for every conceivable scenario.
However, sometimes it is faster. Dealing with many threads has its own problems (e.g. threads sharing CPU cores, thread deadlocking, race conditions, etc). In some cases node's approach is faster, because it doesn't have all that overhead to deal with those issues. In other cases it might not be faster.
That being said, there are things you can do (e.g. worker threads) that can allow you to tailor node.js to your circumstances, if you find you are CPU limited. This is fairly common on web servers, to have as many worker threads as CPU cores. (or cores minus 1, to leave a core free for the OS etc)
Since Node.js 10.5, they introduced the new worker thread which makes Node.js a multi-thread environment.
Previously, with only one thread on Node.js, there's no cpu time slicing happening because of the event driven nature (If I understand correctly).
So now multiple threads on Node with with one physical cpu core, how do they share the cpu? is it the OS scheduler schedule time for each thread to run for various amount of time or what?
Worker threads are advertised as
The Worker class represents an independent JavaScript execution thread.
So something like starting another NodeJS instance but within the same process and with a bare minimum of a communication channel.
Worker threads in NodeJS mimick the Worker API in the modern browsers (not a coincidence, NodeJS is basically a browser without UI and with a few extra JS API) and in that context worker threads are really native threads, scheduled by the OS.
The description quoted above seems to imply that in NodeJS too, worker threads are implemented with native threads rather than with a scheduling managed by NodeJS.
The latter would be useless as this is exactly what the JS event loop coupled with async methods do.
So basically a worker thread is just another "instance" (context) of NodeJS run by another native thread in the same process.
Being a native thread, it is managed and scheduled by the OS. And just like you can run more than one program in a single CPU you can do that with threads (fun fact: in many OSes, threads are the only schedulable entities. Programs are just a group of thread with a common address space and other attributes).
As NodeJS is open source, it is easy to confirm this, see the Worker::StartThread and the Worker::Run functions.
The new thread will execute JS code just like the main one but it has been limited in the way it can interact with the environment (particularly the process itself).
This is in line with the JS approach to multithreading where it is more of "two or more message loops" than real multithreading (where threads are free to interact with each other with all the implication at the architectural level).
I have been working with teaching kids programming in Javascript using a combination of online and self made environment.
At some stage most of the kids encounter a time when they create an infinite loop. In days gone by. an infinite loop was expected to be a child's first program with
10 PRINT "Mike is cool"
20 GOTO 10
Writing something like that in JavaScript is problematic
while(true) {
print("Mike is cool");
}
Doesn't work because of the synchronous nature of JavaScript, and that's something that they will have to learn. The problem isn't that their program doesn't work as expected, but when they run their program the entire world stops!
Some Browsers have enough control remaining to close the window, some just Lock. If you are using an in-browser environment (like jsfiddle, jsbin etc) you don't have enough control to stop the rogue "task"
You can't audit the code beforehand (It literally is the halting problem), but is there any reasonable way of mitigating the symptoms?
The programming environment on Khan Academy seems to achieve this
http://www.khanacademy.org/cs/breaking/4804951998988288
What is it doing to handle the excessive run-time? How is it managing to do this while the while is still running?
You could accomplish this in a browser by using a web worker, which does not lock the UI thread of the web browser because the browser runs a separate thread for the web worker. Your looping code for the example would be run in the web worker.
Web worker threads are an HTML5 feature so this approach will not work on older browsers. You can set breakpoints and debug web workers, at least in Chrome and Safari. You can learn the basics of web worker threads at:
http://www.html5rocks.com/en/tutorials/workers/basics/
If Javascript is a single threaded process and AJAX is asynchronous then how does it happen ?
So at OS level ain't the JS engine making a Non-Blocking I/O call for Ajax ?
Yes, the browser engine is making a non-blocking I/O call for Ajax (when you do a non-blocking ajax call).
There are any number of different ways the browser could implement the ajax networking. The only thing we know for sure is that the ajax i/o request isn't blocking the javascript thread. And, further every browser is free to implement it differently as long as they don't block the JS execution thread and any other threads needed to keep the browser functional during the ajax call.
Under the covers, inside the browser, it could be using a separate OS thread to run the ajax call in a blocking fashion on that thread, it could be using non-blocking i/o on a separate thread, it could be using non-blocking i/o on the javascript interpreter thread (probably unlikely, but possible). It could even be using a separate process to manage networking operations with IPC to communicate between them. Which it chooses is entirely up to the browser implementation as any of those methods will allow the javascript interpreter to keep running while the ajax networking happens asynchronously. It's also possible that different browsers have somewhat different implementations.
Chrome, for example uses a separate process for each browser window which other browsers do not.
I'm writing an application that makes heavy use of the http.request method.
In particular, I've found that sending 16+ ~30kb requests simultaneously really bogs down a Nodejs instance on a 512mb RAM machine.
I'm wondering if this is to be expected, or if Nodejs is just the wrong platform for outbound requests.
Yes, this behavior seems perfectly reasonable.
I would be more concerned if it was doing the work you described without any noticeable load on the system (in which case it would take a very long time). Remember that node is just an evented I/O runtime, so you can have faith that it is scheduling your I/O requests (about) as quickly as the underlying system can, hence it's using the system to it's (nearly) maximum potential, hence the system being "really bogged down".
One thing you should be aware of is the fact that http.request does not create a new socket for each call. Each request occurs on an object called an "agent" which contains a pool of up to 5 sockets. If you are using the v0.6 branch, then you can up this limit by using.
http.globalAgent.maxSockets = Infinity
Try that and see if it helps