-
-
Notifications
You must be signed in to change notification settings - Fork 107
"impl Trait" in stable Rust just arrived #105
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
Conversation
|
I want to issue a 0.12.0 soon-ish before doing that, but thanks for the PR!
Could you rebase on top of current master please?
…On Sat 12 May 2018 at 12:02, swizard0 ***@***.***> wrote:
impl Trait <https://blog.rust-lang.org/2018/05/10/Rust-1.26.html> has
finally out in recent stable 1.26, so we could get rid of all Box-es in
our code.
In theory this means less alloc/free, no vtable method calls, aggressive
compiler inlining and optimization abilities, etc :)
------------------------------
You can view, comment on, or merge this pull request online at:
#105
Commit Summary
- implement `Channel::basic_qos`
- Merge remote-tracking branch 'upstream/master'
- upstream merge smallfix
- get rid of all `Box`
- do not clone by hand
- less strict tokio semver
- tests will not work with `tokio 0.1.1`
- make the same version as in upstream
File Changes
- *M* futures/Cargo.toml
<https://github.com/sozu-proxy/lapin/pull/105/files#diff-0> (2)
- *M* futures/src/channel.rs
<https://github.com/sozu-proxy/lapin/pull/105/files#diff-1> (257)
- *M* futures/src/client.rs
<https://github.com/sozu-proxy/lapin/pull/105/files#diff-2> (102)
- *M* futures/src/transport.rs
<https://github.com/sozu-proxy/lapin/pull/105/files#diff-3> (12)
Patch Links:
- https://github.com/sozu-proxy/lapin/pull/105.patch
- https://github.com/sozu-proxy/lapin/pull/105.diff
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#105>, or mute the thread
<https://github.com/notifications/unsubscribe-auth/AANm3h99QSQiOUk_z5_GTfC3IEwCLSxnks5txrMjgaJpZM4T8Wou>
.
|
bf018bd to
65ba8cb
Compare
Keruspe
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.
Please rebase against current master once more, and this time try not to revert all the recent changes as part of your commit...
futures/src/channel.rs
Outdated
| pub fn create(transport: Arc<Mutex<AMQPTransport<T>>>) -> impl Future<Item = Self, Error = io::Error> + Send { | ||
| let channel_transport = transport.clone(); | ||
| let create_channel = future::poll_fn(move || { | ||
| let mut transport = try_lock_transport!(channel_transport); |
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.
why are you reverting that?
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.
It's probably an automatic merge issue, sorry about it. I'll rebase against master once more.
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.
It's not the only place where you reverted stuff btw, especially this pattern.
And please amend the fixes to your commit
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.
Could you please point me the other places? I couldn't find them reading diff.
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.
It appears you fixed it since the review
futures/src/channel.rs
Outdated
| pub fn access_request(&self, realm: &str, options: &AccessRequestOptions) -> Box<Future<Item = (), Error = io::Error> + Send + 'static> { | ||
| self.run_on_locked_transport("access_request", "Could not request access", |transport| { | ||
| transport.conn.access_request(self.id, realm.to_string(), | ||
| pub fn access_request(&self, realm: &str, options: &AccessRequestOptions) -> impl Future<Item = (), Error = io::Error> + Send { |
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.
Why the move and all the cloning everywhere which wasn't needed before?
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.
The other my option for impl Trait result was the following signature:
pub fn access_request<'a>(&self, realm: &str, options: &'a AccessRequestOptions) -> impl Future<Item = (), Error = io::Error> + Send + 'a {Here I decided to just clone options parameter and put less restrictions for return type. The cloning should be cheap and anyways there is .to_string() invocation which is more expensive because of allocation.
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.
But why is that needed now and wasn't before? Because of the FnOnce change?
futures/src/channel.rs
Outdated
| fn run_on_locked_transport_full<Action, Finished>(&self, method: &str, error: &str, action: Action, finished: Finished, payload: Option<(u16, &[u8], BasicProperties)>) -> Box<Future<Item = Option<bool>, Error = io::Error> + Send + 'static> | ||
| where Action: Fn(&mut AMQPTransport<T>) -> Result<Option<RequestId>, lapin_async::error::Error>, | ||
| fn run_on_locked_transport_full<Action, Finished>(&self, method: &str, error: &str, action: Action, finished: Finished, payload: Option<(u16, &[u8], BasicProperties)>) -> impl Future<Item = Option<bool>, Error = io::Error> + Send | ||
| where Action: FnOnce(&mut AMQPTransport<T>) -> Result<Option<RequestId>, lapin_async::error::Error>, |
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.
Why this FnOnce change?
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.
Because it doesn't compile otherwise. If you believe that there surely must be a Fn, you could try to figure out the signature yourself (I failed personally).
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.
What did the compilation error look like with Fn?
It seems weird to me that impl trait causes such a regression, and if it does, I'd prefer not to use it there.
futures/src/channel.rs
Outdated
| if let Ok(mut transport) = self.transport.lock() { | ||
| match action(&mut transport) { | ||
| Err(e) => Box::new(future::err(Error::new(ErrorKind::Other, format!("{}: {:?}", error, e)))), | ||
| Err(e) => Either::A(future::err(Error::new(ErrorKind::Other, format!("{}: {:?}", error, e)))), |
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.
Why all the Either?
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.
Because here there are two different types to return: futures::FutureResult and futures::PollFn. One has to either Box them (for virtual dispatching) or return an futures alternative (either::Either)
| pulse: PF, | ||
| } | ||
|
|
||
| impl Heartbeat { |
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.
Why are you reverting this too?
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.
That was not a revert, it's rather a refactoring. It is my attempt to avoid Box-ing the pulse field.
If you can find out a better solution that would be great.
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'd prefer to leave it as is actually
65ba8cb to
ec155ee
Compare
|
Okay it's starting to look like I'm trying to persuade you to accept these patches which you really don't like :) Please feel free to reject this pull request completely, it is your own project after all. I've already tested and put the library fork into production with all these |
|
My basic point is:
I haven't given a try at impl trait yet, but regarding the FnOnce, I wonder what the compilation error was with Fn, because the implicaitons of FnOnce actually adds more allocations than it removes because of all the clones. |
If you look carefully the relevant changes you'll see that there is only one new
It's definitely clearer. I moved the future assembling there just because there is no way to choose parameter Maybe there is a way to still avoid |
|
I'll give it further thoughts. |
|
Could you resubmit without the heartbeat part? |
|
What about this solution for It's mostly the same as with regular constructor but the code is in separate function instead. |
|
That could be better. |
6020bab to
e8e7a8a
Compare
|
Stuff in this area has evolved to fix some issues and prepare for 0.12 which will be released real soon now. |
|
okay i'll try to |
e8e7a8a to
97a7c2d
Compare
Keruspe
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.
Mostly LGTM apart from the few comments.
Will merge as soon as those are addressed and 0.12 is out
futures/src/channel.rs
Outdated
| impl<T: AsyncRead+AsyncWrite+Send+'static> Channel<T> { | ||
| /// create a channel | ||
| pub fn create(transport: Arc<Mutex<AMQPTransport<T>>>) -> Box<Future<Item = Self, Error = io::Error> + Send + 'static> { | ||
| pub fn create(transport: Arc<Mutex<AMQPTransport<T>>>) -> impl Future<Item = Self, Error = io::Error> + Send { |
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.
Why are you removing all the 'static lifetimes?
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.
but they are not needed with impl Trait anymore
so I just don't see why leave unnecessary restrictions
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.
They can be needed in some scenarii actually from what I understand, and it doesn't harm to keep those around I'd say.
If we can add some "guarantees" to the return type "for free", I don't see why we should remove those
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.
Are you sure about these "additional guarantees for return type"?
I believe that 'static within type like Box<SomeTrait + 'static> means just "there is no non-static references inside my trait object", isn't it?
And in case of impl Trait compiler already has a full type in its hands so it can easily examine it itself.
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'm not 100% sure, but I really see no harm in keeping those markers in place
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 don't know if there is any harm in them, but they are really not needed :) Even if a generic argument requires 'static the compiler could check it itself (proof: https://play.rust-lang.org/?gist=037be4712b2acfc8411b2725e7ae94ae&version=stable&mode=debug). Probably these markers are added automatically but I'm not sure.
It just works in a different way than in trait objects.
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.
Right
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 realized we can remove Send marker as well! Should I do it?
futures/src/channel.rs
Outdated
| options.mandatory, options.immediate).map(Some) | ||
| }, move |conn, delivery_tag| { | ||
| conn.channels.get_mut(&channel_id).and_then(|c| { | ||
| conn.channels.get_mut(&channel_id).and_then(move |c| { |
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.
Is this needed?
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.
not really i believe
futures/src/channel.rs
Outdated
| } | ||
|
|
||
| fn run_on_locked_transport_full<Action, Finished>(&self, method: &str, error: &str, action: Action, finished: Finished, payload: Option<(Vec<u8>, BasicProperties)>) -> Box<Future<Item = Option<RequestId>, Error = io::Error> + Send + 'static> | ||
| fn run_on_locked_transport_full<Action, Finished>(&self, method: &str, error: &str, action: Action, finished: Finished, payload: Option<(Vec<u8>, BasicProperties)>) -> impl Future<Item = Option<RequestId>, Error = io::Error> + Send |
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.
Can you leave this one unchanged with the Box? I have a few changes locally which will allow making it impl trait without the Either stuff
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.
Do you want to just remove Either or to leave Box in function signature?
If second, we have to box wait_for_answer result as well
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.
Just leave the Boxing for those two for now then please, it'll go away just after :)
|
Sorry for the mess this PR has become, I'm really eager to land this, you just happen to have created it when development was really active to get some bugfix done and I want those bugfixes to be released in a version that does not depend on a compiler from a couple of weeks ago |
97a7c2d to
0b96e4a
Compare
|
Is the current pr okay? I could add |
|
I prefer to keep heartbeat for later. Wrt the + Send + ‘static : after thinking more about it and about your example => indeed that doesn’t change anything for calling code, but it enforces the restrictions inside the library,. This way if for some reason we have an object somewhere which is !Send, the library will fail to build. If we remove the markers, the library will build and some application using it might no longer build. |
|
Ok it sounds reasonable. I'm going to return markers and rebase the pr. |
0b96e4a to
23defb8
Compare
|
@swizard0 thanks, btw. I reworked the heartbeat stuff a bit, not sure if it's worth porting this one to impl trait as it's only 1 box allocation now, and it's only done once per connection so it's quite cheap. |
impl Trait has finally out in recent stable 1.26, so we could get rid of all
Box-es in our code.In theory this means less alloc/free, no vtable method calls, aggressive compiler inlining and optimization abilities, etc :)