Implements request-response communication pattern with an IPC channel provided by Node when child_process.forking.
Consider
// parent.js
const setupIpcSession = require("ipc-request")
const { fork } = require("child_process")
setupIpcSession(fork("./child.js")).then(sendRequest => {
console.log(
"[parent] Hands have been shaken! Now I know that the child process listens to my requests"
)
const requestData = "(REQUEST FROM parent.js)"
console.log("[parent] Sending request: ", requestData)
return sendRequest(requestData).then(responseData => {
console.log("[parent] Got response: ", responseData)
process.exit(0)
})
})
// child.js
const setupIpcSession = require("ipc-request")
setupIpcSession(process, (data, sendResponse) => {
console.log("[child] Got request: ", data)
const responseData = `(RESPONSE FROM child.js TO ${data})`
console.log("[child] Sending response:", responseData)
return sendResponse(responseData).then(() => {
console.log("[child] Response sent: ", responseData)
})
})
Now if you run the parent with
$ node parent.js
you must see a log similar to this
[parent] Hands have been shaken! Now I know that the child process listens to my requests
[parent] Sending request: (REQUEST FROM parent.js)
[child] Got request: (REQUEST FROM parent.js)
[child] Sending response: (RESPONSE FROM child.js TO (REQUEST FROM parent.js))
[parent] Got response: (RESPONSE FROM child.js TO (REQUEST FROM parent.js))
[child] Response sent: (RESPONSE FROM child.js TO (REQUEST FROM parent.js))
In this example, parent.js
sends requests (a "client") and child.js
accepts requests and responds (a "server").
But the "client-server" configuration of this example is not mandatory.
Both child and parent processes can be either "client" or a "server" or a "client" and a "server" at the same time.
I call this handshake procedure a 2-way duplex handshake.
It is 2-way because it involves a handshake request and a handshake response. An analogy is the TCP 3-way handshake.
It is duplex because it establishes a session in which both processes can send requests, and at
the same time receive requests and respond to them.
------------------------------------------------------------------------------------------> time
Parent Process
==========================================================================================
> Run | Setup Session | | Resolve | (Can send
> Child | In Parent (2) | | Promise And | requests
> (1) | |~~~~~~~~~~~~~~~~~~~~~~~| Respond (5) | now)
========|===============|=======================^=============|===========================
| | | |
| | | |
| Child Process | | |
v===============v=======================|=============v===========================
> Ignored (3) Setup Session | | Resolve | (Can send
> In Child (4) | | Promise | requests
> |.............| (6) | now)
==================================================================================
The Parent Process runs the Child Process.
The Parent Process initiates a handshake by a call to the setupIpcSession
function.
2.1. Sets up a user listener for incoming user requests from the Child Process. A user here means a user of the library, a developer.
2.2. Sends handshake request and listens to handshake response.
2.3. Sets handshake request listener. The time period during which the handshake request listener exists
is shown by the line of tildes: ~~~~~~~~~~~~~
.
The handshake request from step 2.2 is in vain because the Child Process
didn't call setupIpcSession
function yet and nothing in the Child Process listens
to handshake request.
The Child Process initiates a handshake the same way as the Parent Process in step (2).
Most importantly, the Child Process sends a handshake request and listens to a handshake response.
Listening to a handshake response is shown by the line of dots: .............
.
The Parent Process listens to handshake requests (~~~~~~~~~~~~~
) and
once it receives such a request, it knows that the Child Process
has request listener for user requests set up. A promise returned from a setupIpcSession
call resolves
with sendRequest
function.
The Child Process listens to handshake response (.............
) and
once it receives this response, it knows that the Parent Process
has request listener for user requests set up. A promise returned from a setupIpcSession
call resolves
with sendRequest
function.