You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// main.jsconstsubprocess=execa('./subprocess.js',{ipc: true});forawait(constmessageofsubprocess.ipc){
... // Can use subprocess.send()}
// subprocess.jsimport{ipc}from'execa';forawait(constmessageofipc){
... // Can use process.send()}
Returning (with return or break) from either the current process or the subprocess' loop automatically returns from the other loop, disconnecting the IPC.
Throwing from either loop throws the same error in the other loop, also disconnecting the IPC. The error is serialized/parsed, so only its message and stack are kept.
The parent loop's waits for the subprocess to resolve. Also, it throws if the subprocess promise is rejected.
Rationale
The above provides with a simpler syntax for IPC, using async iterables instead of events.
It also enforces best practices:
Disconnection
Ensures .disconnect() is called to prevent processes hanging, and allows graceful exits.
Otherwise, by default, the subprocess hangs until calling .disconnect(), which users might forget. Many might call process.exit() in the subprocess, but that's a forceful exit which might interrupt ongoing logic.
Error handling
Proper error handling. Errors during either .send() or message handlers are correctly handled and propagated.
Otherwise, by default, an exception in either case in the subprocess would result in an uncaught exception. The current process would need to check stderr to see the error.
The above proposal propagates the error programatically instead, allowing the current process to catch it and ensuring proper propagation.
Subprocess completion/error
Ensures the subprocess promise is awaited and its errors are propagated.
Usually, if IPC is used, it tends to be during the whole lifetime of the subprocess. I.e. the ipc and subprocess promises overlap and can be combined. subprocess does not need to be awaited if subprocess.ipc is.
What do you think?
Edit: some implementation notes:
The loop should iterate using on(subprocess, 'message') under-the-hood.
Listen to process's and subprocess's error events, making the async iterable throw. This means users do not need to use an error callback on process.send() and subprocess.send().
Users use process.send() and subprocess.send() to send messages, or process.disconnect()/subprocess.disconnect(). We keep those as is.
Call .disconnect() when either loops returns or throws. Only if .disconnected is false. Should wait for the disconnect event.
The parent's iterable.return() and iterable.throw() should return a promise that waits for the subprocess to complete.
Serialize the error using v8.serialize().
Requires ipc: true option.
Parent/subprocess initial messages are buffered by Node.js, so we don't need to wait for the subprocess to start.
for await processes serially. However, users can achieve parallelism by calling async functions without await, although it would make error handling harder (although not impossible).
The text was updated successfully, but these errors were encountered:
Proposal
Returning (with
return
orbreak
) from either the current process or the subprocess' loop automatically returns from the other loop, disconnecting the IPC.Throwing from either loop throws the same error in the other loop, also disconnecting the IPC. The error is serialized/parsed, so only its
message
andstack
are kept.The parent loop's waits for the
subprocess
to resolve. Also, it throws if thesubprocess
promise is rejected.Rationale
The above provides with a simpler syntax for IPC, using async iterables instead of events.
It also enforces best practices:
Disconnection
Ensures
.disconnect()
is called to prevent processes hanging, and allows graceful exits.Otherwise, by default, the subprocess hangs until calling
.disconnect()
, which users might forget. Many might callprocess.exit()
in the subprocess, but that's a forceful exit which might interrupt ongoing logic.Error handling
Proper error handling. Errors during either
.send()
or message handlers are correctly handled and propagated.Otherwise, by default, an exception in either case in the subprocess would result in an uncaught exception. The current process would need to check stderr to see the error.
The above proposal propagates the error programatically instead, allowing the current process to catch it and ensuring proper propagation.
Subprocess completion/error
Ensures the
subprocess
promise is awaited and its errors are propagated.Usually, if IPC is used, it tends to be during the whole lifetime of the subprocess. I.e. the
ipc
andsubprocess
promises overlap and can be combined.subprocess
does not need to be awaited ifsubprocess.ipc
is.What do you think?
Edit: some implementation notes:
on(subprocess, 'message')
under-the-hood.process
's andsubprocess
'serror
events, making the async iterable throw. This means users do not need to use an error callback onprocess.send()
andsubprocess.send()
.process.send()
andsubprocess.send()
to send messages, orprocess.disconnect()
/subprocess.disconnect()
. We keep those as is..disconnect()
when either loops returns or throws. Only if.disconnected
isfalse
. Should wait for thedisconnect
event.iterable.return()
anditerable.throw()
should return a promise that waits for the subprocess to complete.v8.serialize()
.ipc: true
option.for await
processes serially. However, users can achieve parallelism by calling async functions withoutawait
, although it would make error handling harder (although not impossible).The text was updated successfully, but these errors were encountered: