javascriptnode.jsasynchronousasyncsocketreactphp

How async request handling in real cases works?


Most tutorials I have seen for Node JS/ReactPHP is more like, that you don't need to wait a 5 seconds timer to echo something. EventLoop can handle that later.

Like This Example Below (Note this is non-language dependent):

timer(run 5 seconds later){
    print 'username';
}
print ', another text';

// non A-Sync output is like = 'username, another request'
// A-Sync output is like = ', another requestusername'

But this is the same file we are working inside. What if we connect to a i/o socket.

Like This Example: (requestfile.js)

connectSocket(takes 5 seconds to return a result){
    print result;
}

//end of the file

Well I have 2 Questions here (doesnt matter reactphp or nodejs, async matters for me)

1-If we get 2 user requests, the first one connects and waits 5 seconds, can A-Sync run the second request in this same thread while waiting respond callback for the first Request. (or does async only mean, you can do independent operations inside same file like: print footer while connecting this socket for 5 seconds)

2-In Which Core/Thread is EventLoop running? Is it Independent from request Thread. If Not How Don't We Loose Eventloop Process? Who Is(Thread/Core) controlling that, if the socket returned a value? Is EventLoop maybe running every second to check callbacks? (I thought, doesn't matter how fast it is but machine code is running linear synced (one after another))


Solution

    1. An event loop allows your application to answer a second request while the first is still being processed. This is possible because all the I/O operations expect a callback that will be executed when the operation is done. Node.js and PHP are able to run only one thread (natively), but think of it as being able to have only one call stack at a time. Notice that when you pass a callback to a function, you allow the whole call stack to be cleared, and therefore, you also allow another code to run. Example:

      function callback (result) {
          console.log(result);
      }
      
      function handleRequest (request) {
          doSomethingAsync(callback);
      }
      

      Notice that when doSomethingAsync is called, the call stack will look more or less like:

      • doSomethingAsync
      • handleRequest
      • some framework method
      • ...
      • some framework method

      After doSomethingAsync returns (the async operation is still pending) handleRequest also returns, and all the framework stacked methods also can return, but callback hasn't been called yet. When the async operation completes, the callback will be invoked with a clear call stack (in case of node - for ReactPHP you will have the event loop calls in the stack also).

    2. The event loop holds a queue of tasks that are pending, and it will start one task only when the previous one completes. When you call an async function you are indirectly adding a new task to the event loop task queue. So the current task MUST finish in order for the async operation to complete. It is also important to understand that the event loop will never interrupt a task to invoke a callback. A callback is invoked only when a previous task finished (i.e. the call stack becomes empty).

      When the event loop task queue becomes empty, but there are still async operations pending, the event loop might choose to become idle for some amount of time depending on the event loop implementation, till one of the async operations completes.