-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
tokio-uitls: from_parts() for FramedWrite and FramedRead #7763
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
base: master
Are you sure you want to change the base?
tokio-uitls: from_parts() for FramedWrite and FramedRead #7763
Conversation
ADD-SP
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would mind adding some tests for both from_parts and into_parts?
|
@ADD-SP Thanks! I added tests as well. I also noticed that So, solving the task of splitting up Framed will look like: let framed = Framed::from_parts(parts);
let FramedParts {
io,
read_buf,
write_buf,
..
} = framed.into_parts();
let (io_read, io_write) = tokio::io::split(parts.io);
let mut read_parts = FramedParts::new_parts(io_read, Codec::new());
read_parts.read_buf = read_buf;
let framed_read = FramedRead::from_parts(read_parts);
let mut write_parts = FramedParts::new_parts(io_write, Codec::new());
write_parts.write_buf = write_buf;
let framed_write = FramedWrite::from_parts(read_parts);It's far from perfect, but at least doable now. |
|
Thanks for the context! I'm considering deprecating the |
|
I end up with |
| }; | ||
| } | ||
|
|
||
| const INITIAL_CAPACITY: usize = 8 * 1024; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a comment that this must be the same as the non-public constant at https://github.com/Mrreadiness/tokio/blob/52fcebcaea1e7f6930d1f21e84b59e36ae22d725/tokio-util/src/codec/framed_impl.rs#L25
| inner: FramedImpl { | ||
| inner: parts.io, | ||
| codec: parts.codec, | ||
| state: parts.read_buf.into(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This loses the eof and has_errored flags - https://github.com/Mrreadiness/tokio/blob/52fcebcaea1e7f6930d1f21e84b59e36ae22d725/tokio-util/src/codec/framed_impl.rs#L76-L77
Is this OK ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I replicated the same behaviour as in Framed.
As I understood from the state machine, it's okay.
has_error - used in 2 cases:
- Error from "previous" Decoder. A user already saw this error and intentionally created a new
Framed(probably with another Decoder) to try to decode again. - Error from underlying IO. I'm not 100% sure, but I suppose we get the same error with the next read attempt. A user saw this IO error as well.
For eof, we should restore this knowledge with the next call to the underlying IO here. As I understood from AsyncRead docs, the expected behavior after reaching EOF is Ok(Ready) with 0 new bytes for all subsequent read attempts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realised that these 2 flags are related to IO, and the user can change parts.io. So we don't have any other way to get this knowledge back, but to interact with IO itself.
How about |
@martin-g The |
Co-authored-by: Martin Grigorov <[email protected]>
Implement
from_parts()forFramedWriteandFramedRead.Motivation
Thanks to #7566,
FramedWriteandFramedReadcan be transformed intoFramedParts, but there is no way to create them back from parts, or to transformFramedintoFramedReadorFramedWritewithout losing progress in buffers.My original problem was splitting
Framedinto bothFramedReadandFramedWrite, to swap the codec for one of them withmap_codec. I wish we could have something likeinto_splitforFramed:But cloning of the codec doesn't feel right here. So, with
from_parts, a user will have more control over the reader and writer reconstruction.Solution
Implement
from_parts()forFramedWriteandFramedRead, which builds those structures fromFramedPartsand preserves internal buffers.