Most NodeJS programmers know why it's bad to block NodeJS's single-threaded event loop. For example, when reading a file, we know it's better to use fs.readFile instead of fs.readFileSync. My question is: how does one go about creating an asyn API in the first place if the underlying task to be performed by the API is inherently synchronous? Another words, how do I go about creating an API such as fs.readFileSync, and not use the event-loop thread to perform the underlying task? Do I have to go outside of NodeJS & Javascript to do this?
1 Answers
how does one go about creating an asyn API in the first place if the underlying task to be performed by the API is inherently synchronous?
In node.js, there are the following choices for creating your own asynchronous operation:
- Base it on existing async operations (such as
fs.readFile()
). If your main operation itself is synchronous and can only be done synchronously in node.js, then this option would obviously not solve your problem. - Break your code into small chunks using
setTimeout()
,setImmediate()
ornextTick()
so that other things can interleave with your operation and you won't block other things from sharing the CPU. This doesn't prevent CPU usage, but it does allow sharing of the CPU with other operations. Here's an example of iterating over an array in chunks that doesn't block other operations from sharing the CPU: Best way to iterate over an array without blocking the UI. - Move your synchronous operation into another process (either another node.js process or any other process) that can do its thing and then communicate back asynchronously when done using any appropriate inter-process communication mechanism (TCP, stdio, etc...).
- Write a node.js plug-in where you have the ability to use native OS threading or native IO events and you can then create a new operation in node.js that has an async interface.
Do I have to go outside of NodeJS & Javascript to do this?
Items #1, #2, #3 above can all be done from Javascript. Item #4 involves create a native code plug-in (where you can have access to native threading).
Another words, how do I go about creating an API such as fs.readFileSync
To truly create an API like fs.readFileSync()
from scratch, you would have to use either option #3 (do it synchronously, but in another process and then communicate back the result asynchronously) or option #4 (access OS services at a lower level than is built into node.js via a native code plug-in).
-
4 seems most efficient if 1 is not available. What's the best way of integrating NodeJS with modules written in another language? I have some multi-threaded Java modules that do financial calculations. I was thinking of packaging those modules into a TCP/IP server and have my NodeJS application access the server via TCP. Do you think that's the best way of doing it? – ptmoy2 Mar 20 '16 at 19:50
-
@ptmoy2 - Packaging those modules into a TCP/IP server is certainly one way of doing it and is often clean to implement as the entire interface is TCP/IP which is easily and cleanly understood by all. It is a much more complicated question to assess what is the "best" way among the choices to do it as "best" would depend upon a whole bunch of things which we haven't even begun to discuss and would probably ultimately require some benchmarking of certain scenarios to determine. – jfriend00 Mar 20 '16 at 19:55
-
@ptmoy2 - If you want to change your query to "Is putting it in another TCP server and accessing it via TCP an acceptable solution", then the answer to that is usually "Yes". – jfriend00 Mar 20 '16 at 19:56