/ipc-request

Implements request-response communication pattern with an IPC channel provided by Node when `child_process.fork`ing

Primary LanguageJavaScriptMIT LicenseMIT

I P C - R E Q U E S T

Implements request-response communication pattern with an IPC channel provided by Node when child_process.forking.

Example

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.

Handshake procedure

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.

Handshake step by step

------------------------------------------------------------------------------------------> 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)
        ==================================================================================

(1) Run Child

The Parent Process runs the Child Process.

(2) Setup Session In Parent

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: ~~~~~~~~~~~~~.

(3) Ignored

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.

(4) Setup Session In Child

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: ..............

(5) Resolve Promise And Respond

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.

(6) Resolve Promise

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.