2

If I have an SMTP server (like haraka) or a web server (like Express) that uses Node.js and I have to use a sync function that could not convert to be Async what would happen?

If I have to make an HTTP Request in a syncronous way the server will be hanged to all users until the http request is finished or be hanged only to the current user/email? Will the processing of all users be paused?

JohnnyHK
  • 305,182
  • 66
  • 621
  • 471
Ricardo Polo Jaramillo
  • 12,110
  • 13
  • 58
  • 83
  • What does the synchronous function do anyway that requires it to be blocking? – mscdex Dec 29 '15 at 03:12
  • @mscdex I had to go to with this answer http://stackoverflow.com/a/34503584/909974. Any better idea? :) – Ricardo Polo Jaramillo Dec 29 '15 at 03:13
  • Unless you're using node clustering, all other requests (for all users) will be blocked until the sync function completes. – JohnnyHK Dec 29 '15 at 03:20
  • @RicardoPolo Network I/O in node never blocks, so that question/answer you linked to does not apply (instead it's a browser-only thing). – mscdex Dec 29 '15 at 06:17
  • @mscdex but if you use https://github.com/driverdan/node-XMLHttpRequest it locks... isnt it? – Ricardo Polo Jaramillo Dec 29 '15 at 14:00
  • @RicardoPolo Modules like that should be avoided at all costs IMHO. That module does sync network I/O by shelling out to a process and [explicitly incorporating a busy loop to "fake it."](https://github.com/driverdan/node-XMLHttpRequest/blob/554280a7c509c1ce4d7ad9516b46d182739e8026/lib/XMLHttpRequest.js#L504-L506). That means you're performing a lot of unnecessary filesystem polling and using an extra amount of CPU. – mscdex Dec 29 '15 at 14:21
  • @mscdex thanks. Do you have any other idea differente that this locking libraries that may help to fix this? http://stackoverflow.com/questions/34503495/assing-variable-from-inner-callback/ – Ricardo Polo Jaramillo Dec 29 '15 at 14:47

2 Answers2

2

To understand the answer to your question, you really need to understand the node.js event loop. I highly recommend visiting that SO link and following a few of the links there.

If you must perform a synchronous operation, be aware that yes, a synchronous call will block all other requests on that process. If you want more than one client/remote to be served concurrently, then you'll definitely want to use the cluster module baked into node.js to spawn concurrent processes.

Also, if your synchronous operation is slow enough to impact your QoS, then it'd be a very smart idea to get familiar with process.nextTick and prevent your processes from being completely stalled while waiting for a sync operation to complete.

Community
  • 1
  • 1
Matt Simerson
  • 1,001
  • 1
  • 10
  • 22
  • Reading one the answers it says 'When an event that blocks I/O is retrieved from the event queue, Node.js retrieves a thread from the thread pool, and executes the function there instead of on the main event loop thread. This prevents the blocking I/O from holding up the rest of the events in the event queue'. In there I understand it don't block because it uses other thread. Am I understanding wrong? Thanks!!! – Ricardo Polo Jaramillo Dec 29 '15 at 04:48
  • Or maybe his answer is wrong. In all other links it says that there is only one thread – Ricardo Polo Jaramillo Dec 29 '15 at 04:56
  • We're back to that event loop. In the case you cite, where node is performing some disk/network I/O, the request is **by default** made asynchronously, unless it calls a function with the word 'sync' in the name. One way to think of it is, "node initiates the request and then does nothing else with it until the result comes back. IE, it continues processing all the other tasks on the event loop. **Later**, when the results arrive, that function is put back onto the event loop and continues processing. – Matt Simerson Dec 29 '15 at 04:57
  • FWIW the thread pool is not used at all for network I/O. The thread pool is only used for async file I/O, dns.lookup(), and a couple other things. – mscdex Dec 29 '15 at 06:16
  • 1
    Also, using clustering where workers each do both the http request handling AND synchronous tasks is not ideal. If you really have something that is blocking/CPU intensive, it's probably better to have `n` child processes (where `n` depends on your needs/use case) that basically pull work items off a queue and notify the master process when they're done with each work item. – mscdex Dec 29 '15 at 06:20
0

As far as I know, synchronous requests are not blocking all users, but before I do something like that, if I am not absolutely sure, I conduct a few tests. Using futures or other libraries, one can send synchronous requests, which is sub-optimal indeed, but if the developer does not have the rights/possibility to work with all the source-code, then it might be a necessary evil.

If this is done on the client-side (not this case, but let's clarify anyway), then a synchronous request from a browser looks like this:

funcion Foo(){
   var request = new XMLHttpRequest();
   request.open("GET", "http://server.com", false);
   request.send();
   function handleResponse(response) {
      console.log(response);
   }
   handleResponse(request.responseText);
}
Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175