Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IPC should leverage the fact that UnixDomainSockets are fully duplex #8258

Open
mralj opened this issue Feb 24, 2025 · 0 comments
Open

IPC should leverage the fact that UnixDomainSockets are fully duplex #8258

mralj opened this issue Feb 24, 2025 · 0 comments

Comments

@mralj
Copy link
Contributor

mralj commented Feb 24, 2025

IMPORTANT:
I could be misunderstanding the code; maybe we already do have support for the improvement I'm proposing here!

Is your feature request related to a problem? Please describe.
For JSON RPC over IPC, we are using Unix Domain Sockets (UDS) (link). These UnixDomainSockets are available since Windows 10/Windows Server 2019 (and ofc. much longer on Unix/Linux). They offer fur duplex communication support, meaning we can read and write simultaneously using a single socket connection.

My C# is a bit Rusty 🦀, but unless I misunderstand the code, we have the following:

  1. Reader loop starts: link
  2. If there is enough bytes, process them (and await): link
  3. Here is the code for process&write loops: link

As far as I can see, while all of these calls are async there is no concurrency/parallelism here, meaning this is how I read the execution:

  1. Read message 1
  2. Process message 1
  3. Write a response to message 1
  4. Read message 2
  5. Process message 2
  6. ...

As far as I can tell, all new reads are blocked till the previous write(s) are finished. IMO, this is suboptimal; the UDS (and, by extension, WebSockets) offers a fully duplex connection, meaning we can read and write simultaneously. How this is implemented, one s_low-to-process(or bad)-request_ can strain (block) the whole system.

Describe the solution you'd like
We should take advantage of UDS's full-duplex connection and handle reading and processing/writing separately.

Additional context
Here is how I implemented this for rbuilder - in a standalone Rust crate(library), it has (hopefully) an easy-to-understand graphical representation of the system I'm proposing.

The system depicted in the issue is, I think, a bit more complicated than what we actually need in NMC. This is because reipc acts as a client and needs to attribute incoming data as responses to corresponding requests correctly.

Whereas NMC acts as a server, it should:

  1. Have reader loop
  2. Once the message is received & parsed, it can be offloaded to the processor (which shouldn't block the reader loop)
  3. Once the processor is finished, it writes the response

Some of the open Qs (if we go with the architecture proposed above):

  • What will be the boundaries? Will the reader just read bytes and leave the parsing to the processor? Will the processor also write a response, or shall we have a separate writer loop (as we do with the reader)
  • As far as I see, the processor will be the bottleneck. I think we should have multiple processors (e.g., at least 2) so that one bad request doesn't hog the whole IPC
  • I propose using channels as impl. solution as they should be well suited for this task. Moreover using channels should simplify some of the code we already have (e.g. reading this they already use the same primitives for the data protection as we do here)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant