Eolu / ipipe

Cross-platform named-pipe library for Rust
29 stars 5 forks source link

Achieve platform-agnostic functionality #5

Open Eolu opened 3 years ago

Eolu commented 3 years ago

Testing has been limited, so right now it's almost certain that some things will behave differently on Windows compared to Unix platforms. This issue exists to document semantic differences among platforms.

Eolu commented 3 years ago

Windows returns immediately on write if no reader is present, Linux blocks until something is written.

Explanation: On Linux the concept of "connection" to the pipe is invisible from either side. The writer isn't aware until something is read, and the reader isn't aware until something is written. On Windows the reader is the server and the writer must make a new handle after a reader connects. This reconnection is implemented in ipipe but the writer doesn't block for writes in the meantime.

Current Windows implementation: If a write fails with "ERROR_NO_DATA", then a new handle is initialized. The write is then attempted again. If that or any other error occur a that point, it's considered a failed write and the error is returned.

Eolu commented 2 years ago

See Multiple handles to same pipe can behave incorrectly

gggto commented 2 years ago

As https://github.com/Eolu/ipipe/issues/13#issuecomment-1080032061 suggest, cross-platform behaviour is, well, not quite there. We talked earlier in https://github.com/Eolu/ipipe/issues/12 about possible solutions.

While looking for an async equivalent of ipipe, I stumbled upon parity-tokio-ipc, and was wondering if that crate couldn't serve as an inspiration for ipipe.

So, if I am not entirely mistaken, this crate uses tokio's equivalent of UnixListener and UnixStream, and tokio's named_pipe module (which might also be an inspiration). These structs allow for tcp-like communication, which can then be os-abstracted "seamlessly".

Therefore, I think that maybe something like a PipeListener-PipeStream combo might be achievable, which could avoid the hassle of the current "there is no server (actually there is)" design.

Eolu commented 2 years ago

parity-tokio-ipc definitely seems useful for this. I'd like to take a look into it when I find the time. It might be a good solution here.

But on another note, after quite a bit of discussion on the state of this crate and the best way to move forward, I came to a few conclusions: A least-common-denominator API means by definition that some degree of features from both APIs will have to be limited. This will almost inevitably result in an API opinionated towards some particular purpose (or an API with lots of cfg flags to turn things on and off).

A cleaner architecture is probably to split this into separate crates for both the Unix and the Windows pipes that each aim to eventually be as complete an API as possible. Then this crate could build off of that and offer specific opinionated cross-platform uses of either of the platform-specific crates.

uglyoldbob commented 1 year ago

The interprocess crate is a potential option for this.