IPC framework based on tarpc #20
Conversation
|
@pawelchcki is this PR still relevant, or can we close it? (It looks like #45 is a superset) |
|
@ivoanjo sorry I missed the notification :|
This PR is actually a superset of #45 😅 |
13f04c5 to
012f383
Compare
Includes the ability to transfer file descriptors between processes, and provides both an async (tokio based) interface as well as synchronous interface
6673374 to
d876750
Compare
"ignored" tests group
dfafc80 to
8e68344
Compare
9e24d80 to
395ca65
Compare
f3cbf47 to
5750f1d
Compare
| let mut fds = [0; MAX_FDS]; | ||
|
|
||
| unsafe { | ||
| let b = &mut *(buf.unfilled_mut() as *mut [std::mem::MaybeUninit<u8>] as *mut [u8]); |
There was a problem hiding this comment.
This unsafe behavior. You're casting uninitialiased memory to a &mut [u8]. You should call initialize_unfilled instead which will take care of zeroing the memory before.
There was a problem hiding this comment.
Yeah, I think filling with zero's would be safer, and more secure.
I basically followed what tokio AsyncRead was doing here.
This is part of their optimization - since its a buffer that will be written to - then the contents of memory don't matter as much. But I'd prefer to play on the safe side here
| self.send_request(req).await; | ||
| self.deadlines.schedule_next_heartbeat(); | ||
| self.data.started = true; | ||
| if !self.data.started { |
| let b = &mut *(buf_window.unfilled_mut() | ||
| as *mut [std::mem::MaybeUninit<u8>] | ||
| as *mut [u8]); |
There was a problem hiding this comment.
Same comment for the &mut [u8]
6e0579b to
ecdd9b8
Compare
|
Thanks @paullegranddc for the review 🙇! 🎉 |
What does this PR do?
Implement a msgpack based RPC / IPC. Where a server is spawned in an async context, and clients can be either async or sync. In addition the RPC can be used in a 1 way style. Where messages are simply sent onto a pipe, without requiring reading of any responses.
This way we can optimize for cases where data transmission is simply in a single direction.
This RPC framework uses
tarpccrate and adds to it possibility to submit RPC requests without using tokio, and also transport FileDescriptors that can be used to safely delegate processing to the sidecar process.See example use here:
https://github.com/DataDog/libdatadog/pull/20/files#diff-b5cbb946eecfad576b88206a0a05bf1a78331d41fcd5842db73e9b902831a202R26
Some quick benchmarks
write only interface time: [1.8545 µs 1.9404 µs 2.0843 µs] change: [-0.9627% +12.268% +31.181%] (p = 0.13 > 0.05) No change in performance detected. Found 4 outliers among 100 measurements (4.00%) 4 (4.00%) high severe two way interface time: [18.007 µs 19.087 µs 20.356 µs] change: [-15.207% -4.5682% +5.7143%] (p = 0.47 > 0.05) No change in performance detected. Found 11 outliers among 100 measurements (11.00%) 6 (6.00%) low mild 4 (4.00%) high mild 1 (1.00%) high severeMotivation
In some cases the context of data we process needs to live longer than a os process that produces it. For these cases we can spawn a subprocess that will receive the data from producers - and later transform and send to the backend/agent.
For efficient operation we need an optimized RPC, and a method to coordinate sidecar lifecycle.