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

Change AioCb to primarily use Bytes instead of Rc<[u8]> #820

Merged
merged 4 commits into from
Jan 21, 2018

Conversation

asomers
Copy link
Member

@asomers asomers commented Dec 21, 2017

Rc<[u8]> isn't a very good buffer type to use for aio. For one thing, it lacks interior mutability. For another, a single Rc<[u8]> can't be carved up into smaller buffers of the same type. Bytes and BytesMut fix both problems. This PR removes the ability to construct an AioCb from Rc<[u8]> and adds the ability to construct one from Bytes, BytesMut, or raw pointers (for consumers who need even more flexibility). At this stage, the PR has the following warts:

  1. A hack is necessary to force small Bytes buffers to allocate on the heap. I plan to fix this with an enhancement to the bytes crate.
  2. The AioCb::buffer method is necessary due to a deficiency in the tokio-core crate. Once I fix that, then only AioCb::into_bufferwill need to be public.

///
/// It is an error to call this method while the `AioCb` is still in
/// progress.
pub fn buffer(&mut self) -> Buffer<'a> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to make this return a Result type instead of having failing if the in progress invariant is broken?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think not. If we do that, then AioCb::into_buffer will need to be able to handle it, such as by returning None. However, that method can already return Buffer::none, which means something different. It would be confusing to return two different None types.

In my experience, your program's flow should make it obvious whether any given AioCb is still in progress or not. Treating an in-progress AioCb as though it has already finished is almost always going to be a programming bug. So I think asserting is appropriate.

@Susurrus
Copy link
Contributor

Susurrus commented Jan 4, 2018

Any movement on this?

@asomers
Copy link
Member Author

asomers commented Jan 4, 2018

Yeah, I'm 99% done modifying the downstream crates. But I can't be confident that my new API will work until I'm 100% done.

@Susurrus
Copy link
Contributor

Susurrus commented Jan 7, 2018

Got an ETA on this? We're at 6 months since our last release, and I think it's smart that we get this out the door instead of waiting. How would you feel about releasing 0.10 now?

@asomers asomers force-pushed the aio_bytes branch 2 times, most recently from 0b18352 to b2ab037 Compare January 8, 2018 01:15
@asomers asomers changed the title WIP: Change AioCb to primarily use Bytes instead of Rc<[u8]> Change AioCb to primarily use Bytes instead of Rc<[u8]> Jan 8, 2018
@asomers
Copy link
Member Author

asomers commented Jan 11, 2018

I'm all satisfied with this change now. Review at your leisure.

Copy link
Contributor

@Susurrus Susurrus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the AIO API very well, so this is mostly minor nits I'm pointing out.

One thing that would have helped me in reviewing this would be to see more doccomment examples for this subsystem. Since this is a refactoring, it can be helpful for users to see specific examples in the documentation (even if some are already included in tests). Could you think of some small examples that would make sense to add to the doccomments for any of the code you've touched? There's no module-level docs for this API, otherwise I'd suggest to throw them in there, but maybe this is a good time to add some?

src/sys/aio.rs Outdated
boxed(Rc<Box<[u8]>>),
/// Immutable shared ownership `Bytes` object
// Must use out-of-line allocation so the address of the data will be
// stable. Bytes and BytesMut sometimes dynamically allocate a buffer, and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backticks around Bytes and BytesMut

src/sys/aio.rs Outdated
#[derive(Clone, Debug)]
enum Keeper<'a> {
pub enum Buffer<'a> {
none,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a doccomment for this variant?

Additionally, why is this lowercase none? I'd expect it to be None.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not for any good reason. I'll change it back. However, I'm wondering if I should make the Buffer type private. If I do that, then I'll have to replace AioCb::into_buffer with AioCb::into_bytes -> Option<Bytes> and AioCb::into_bytes_mut -> Option<BytesMut>. Do you think that would be a better API?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind. I forgot that I can't do that due to a limitation of tokio-core. In order to satisfy tokio-core, I need way to get the Buffer without consuming the AioCb.

CHANGELOG.md Outdated
@@ -107,6 +105,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
([#648](https://github.com/nix-rust/nix/pull/648))

### Removed
- `AioCb::from_boxed_slice` has been removed. It was never actually safe.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would be the replacement for this kind of functionality? If there's a short answer, it should be said here, otherwise it should be stated to "read the docs for more details" or "see the PR for more details". We should make it as easy as possible for downstream users of our library to update their code, this means pointing them in the right direction when we break it.

Cargo.toml Outdated
@@ -18,6 +18,11 @@ bitflags = "1.0"
cfg-if = "0.1.0"
void = "1.0.2"

# Don't include the optional serde feature
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move this comment to right about the default-features line so it's more clear that's what it's pertaining to?

CHANGELOG.md Outdated
@@ -7,7 +7,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).

### Added
- Added `AioCb::from_ptr` and `AioCb::from_mut_ptr`
([#TODO](https://github.com/nix-rust/nix/pull/TODO))
([#820](https://github.com/nix-rust/nix/pull/820))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the initial commit to have this number from the start.

CHANGELOG.md Outdated
@@ -58,8 +58,6 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Changed
- Use native `pipe2` on all BSD targets. Users should notice no difference.
([#777](https://github.com/nix-rust/nix/pull/777))
- `AioCb::from_boxed_slice` no longer allows `aio_read`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why we have this step fixing up from_boxed_slice only to remove it in the following commit?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really. I should squash them together.

@asomers
Copy link
Member Author

asomers commented Jan 14, 2018

@Susurrus I think I responded to all of your concerns except the one about squashing. I left everything unsquashed for your viewing pleasure.

Copy link
Contributor

@Susurrus Susurrus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, you've done a great job with the docs, great job! I'm hoping we can get to this level of documentation for all of nix this year (#nix2018).

Besides the minor nits I brought up on specific lines, I did have two comments that apply to a few places in the code:

  • For the Examples, could you provide a brief summary of what's happening? Just a sentence is fine, but it can be helpful for new users to have context before they start diving into the code as the user may not even be wanting to read that example.
  • For the Safety sections, generally this is supposed to explain what invariants must by held by the caller/programmer that makes the function unsafe. This section is supposed to explain how to use the function safely, not just warn the user that the function is unsafe (the function definition and compiler errors about them needing to specify the call as unsafe should take care of that).

With those changes made, I'm r+ on this. Love that it improves our safety and docs so much!

src/sys/aio.rs Outdated
//! [kevent](../signal/enum.SigevNotify.html#variant.SigevKevent).
//!
//! Multiple operations may be submitted in a batch with
//! [`lio_listio`](fn.lio_listio.html), thought the standard does not guarantee
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thought -> though

CHANGELOG.md Outdated
@@ -6,6 +6,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]

### Added
- Added `AioCb::from_ptr` and `AioCb::from_mut_ptr`
([#820](https://github.com/nix-rust/nix/pull/TODO))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This first link should be removed.

src/sys/aio.rs Outdated
/// result and handle operations that were not canceled or that have already
/// completed.
///
/// See also
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rephrase to indicate this is an external link like "See the man pages for aio_cancel for more details." This applies for all the uses of "See also LINK".

@Susurrus
Copy link
Contributor

Absolutely beautiful! I think this is the new standard for our docs in nix.

Go ahead and squash with a good commit message and then LGTM, assuming the tests pass (i386 FreeBSD is failing still).

It's not actually safe to read into an `Rc<[u8]>`.  It only worked
because of a coincidental `unsafe` block.  Replace that type with
`BytesMut` from the bytes crate.  For consistency's sake, use `Bytes`
for writing too, and completely remove methods relating to `Rc<[u8]>`.
Note that the `AioCb` will actually own the `BytesMut` object.  The
caller must call `into_buffer` to get it back once the I/O is complete.

Fixes nix-rust#788
@asomers
Copy link
Member Author

asomers commented Jan 17, 2018

Travis is back up now. I'm going to go ahead and merge this even though the last OSX builds never ran, because the last changes I made were just formatting stuff that shouldn't have broken OSX.

bors r+ susurrus

bors bot added a commit that referenced this pull request Jan 17, 2018
820: Change AioCb to primarily use Bytes instead of Rc<[u8]> r=asomers a=asomers

`Rc<[u8]>` isn't a very good buffer type to use for aio.  For one thing, it lacks interior mutability.  For another, a single `Rc<[u8]>` can't be carved up into smaller buffers of the same type.  `Bytes` and `BytesMut` fix both problems.  This PR removes the ability to construct an `AioCb` from `Rc<[u8]>` and adds the ability to construct one from `Bytes`, `BytesMut`, or raw pointers (for consumers who need even more flexibility).  At this stage, the PR has the following warts:

1. A hack is necessary to force small `Bytes` buffers to allocate on the heap.  I plan to fix this with an enhancement to the bytes crate.
2. The `AioCb::buffer` method is necessary due to a deficiency in the tokio-core crate.  Once I fix that, then only `AioCb::into_buffer`will need to be public.
@Susurrus
Copy link
Contributor

🤞

@bors
Copy link
Contributor

bors bot commented Jan 17, 2018

Timed out

@Susurrus
Copy link
Contributor

bors r+

bors bot added a commit that referenced this pull request Jan 17, 2018
820: Change AioCb to primarily use Bytes instead of Rc<[u8]> r=Susurrus a=asomers

`Rc<[u8]>` isn't a very good buffer type to use for aio.  For one thing, it lacks interior mutability.  For another, a single `Rc<[u8]>` can't be carved up into smaller buffers of the same type.  `Bytes` and `BytesMut` fix both problems.  This PR removes the ability to construct an `AioCb` from `Rc<[u8]>` and adds the ability to construct one from `Bytes`, `BytesMut`, or raw pointers (for consumers who need even more flexibility).  At this stage, the PR has the following warts:

1. A hack is necessary to force small `Bytes` buffers to allocate on the heap.  I plan to fix this with an enhancement to the bytes crate.
2. The `AioCb::buffer` method is necessary due to a deficiency in the tokio-core crate.  Once I fix that, then only `AioCb::into_buffer`will need to be public.
@bors
Copy link
Contributor

bors bot commented Jan 17, 2018

Timed out

@asomers
Copy link
Member Author

asomers commented Jan 18, 2018

Try try again

bors r+ susurrus

bors bot added a commit that referenced this pull request Jan 18, 2018
820: Change AioCb to primarily use Bytes instead of Rc<[u8]> r=asomers a=asomers

`Rc<[u8]>` isn't a very good buffer type to use for aio.  For one thing, it lacks interior mutability.  For another, a single `Rc<[u8]>` can't be carved up into smaller buffers of the same type.  `Bytes` and `BytesMut` fix both problems.  This PR removes the ability to construct an `AioCb` from `Rc<[u8]>` and adds the ability to construct one from `Bytes`, `BytesMut`, or raw pointers (for consumers who need even more flexibility).  At this stage, the PR has the following warts:

1. A hack is necessary to force small `Bytes` buffers to allocate on the heap.  I plan to fix this with an enhancement to the bytes crate.
2. The `AioCb::buffer` method is necessary due to a deficiency in the tokio-core crate.  Once I fix that, then only `AioCb::into_buffer`will need to be public.
@bors
Copy link
Contributor

bors bot commented Jan 18, 2018

Timed out

@asomers
Copy link
Member Author

asomers commented Jan 18, 2018

If at third you don't succeed, try try again.

bors r+ susurrus

bors bot added a commit that referenced this pull request Jan 18, 2018
820: Change AioCb to primarily use Bytes instead of Rc<[u8]> r=asomers a=asomers

`Rc<[u8]>` isn't a very good buffer type to use for aio.  For one thing, it lacks interior mutability.  For another, a single `Rc<[u8]>` can't be carved up into smaller buffers of the same type.  `Bytes` and `BytesMut` fix both problems.  This PR removes the ability to construct an `AioCb` from `Rc<[u8]>` and adds the ability to construct one from `Bytes`, `BytesMut`, or raw pointers (for consumers who need even more flexibility).  At this stage, the PR has the following warts:

1. A hack is necessary to force small `Bytes` buffers to allocate on the heap.  I plan to fix this with an enhancement to the bytes crate.
2. The `AioCb::buffer` method is necessary due to a deficiency in the tokio-core crate.  Once I fix that, then only `AioCb::into_buffer`will need to be public.
@bors
Copy link
Contributor

bors bot commented Jan 18, 2018

Timed out

@Susurrus
Copy link
Contributor

Travis is still having a tough time with Mac builds. Let's wait a couple of days until the backlog dies down a bit and we can try again.

@asomers
Copy link
Member Author

asomers commented Jan 19, 2018

I see that libc was able to run OSX builds on Travis. Maybe we can too.

bors r+ susurrus

bors bot added a commit that referenced this pull request Jan 19, 2018
820: Change AioCb to primarily use Bytes instead of Rc<[u8]> r=asomers a=asomers

`Rc<[u8]>` isn't a very good buffer type to use for aio.  For one thing, it lacks interior mutability.  For another, a single `Rc<[u8]>` can't be carved up into smaller buffers of the same type.  `Bytes` and `BytesMut` fix both problems.  This PR removes the ability to construct an `AioCb` from `Rc<[u8]>` and adds the ability to construct one from `Bytes`, `BytesMut`, or raw pointers (for consumers who need even more flexibility).  At this stage, the PR has the following warts:

1. A hack is necessary to force small `Bytes` buffers to allocate on the heap.  I plan to fix this with an enhancement to the bytes crate.
2. The `AioCb::buffer` method is necessary due to a deficiency in the tokio-core crate.  Once I fix that, then only `AioCb::into_buffer`will need to be public.
@Susurrus
Copy link
Contributor

libc has a paid Travis subscription, so they can almost always run jobs. Note that the Open Source Mac build queue is almost 3000; this isn't going to finish.

@bors
Copy link
Contributor

bors bot commented Jan 19, 2018

Timed out

@Susurrus
Copy link
Contributor

Mac OS build queue down to 1100, so maybe this could actually happen now!

bors r+

bors bot added a commit that referenced this pull request Jan 21, 2018
820: Change AioCb to primarily use Bytes instead of Rc<[u8]> r=Susurrus a=asomers

`Rc<[u8]>` isn't a very good buffer type to use for aio.  For one thing, it lacks interior mutability.  For another, a single `Rc<[u8]>` can't be carved up into smaller buffers of the same type.  `Bytes` and `BytesMut` fix both problems.  This PR removes the ability to construct an `AioCb` from `Rc<[u8]>` and adds the ability to construct one from `Bytes`, `BytesMut`, or raw pointers (for consumers who need even more flexibility).  At this stage, the PR has the following warts:

1. A hack is necessary to force small `Bytes` buffers to allocate on the heap.  I plan to fix this with an enhancement to the bytes crate.
2. The `AioCb::buffer` method is necessary due to a deficiency in the tokio-core crate.  Once I fix that, then only `AioCb::into_buffer`will need to be public.
@bors
Copy link
Contributor

bors bot commented Jan 21, 2018

@bors bors bot merged commit c3ff37b into nix-rust:master Jan 21, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants