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

refactor(swarm): remove deprecated inject calls #3264

Merged
merged 16 commits into from
Jan 12, 2023

Conversation

jxs
Copy link
Member

@jxs jxs commented Dec 20, 2022

Description

Finishes work first started with #2832

Notes

review by commit is suggested :)

Links to any relevant issues

Open Questions

Change checklist

  • I have performed a self-review of my own code
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • A changelog entry has been made in the appropriate crates

@jxs jxs changed the title Remove inject calls from swarm refactor: remove inject calls from swarm Dec 20, 2022
@jxs jxs changed the title refactor: remove inject calls from swarm refactor(swarm): remove deprecated inject calls Dec 20, 2022
Copy link
Contributor

@thomaseizinger thomaseizinger left a comment

Choose a reason for hiding this comment

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

Nice, thanks for following up on that!

I think we can simplify some of this a bit. Let me know if you need more input :)

swarm/src/handler.rs Show resolved Hide resolved
#[allow(deprecated)]
handler.inject_fully_negotiated_outbound(output, info)
(Either::Left(handler), EitherOutput::First(output), Either::Left(info)) => {
handler.on_connection_event(ConnectionEvent::FullyNegotiatedOutbound(
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems weird that we need to match on the event here (line 174). I think it would be better if we added a

impl ConnectionEvent<EitherOutput, EitherOutput, Either, Either> { }

block where we map the entire event into a Either<ConnectionEvent, ConnectionEvent> so you can directly dispatch the event to the left or the right handler.

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah, that would be great. I tried:

impl<'a, R, L>
    ConnectionEvent<
        'a,
        EitherUpgrade<SendWrapper<L::InboundProtocol>, SendWrapper<R::InboundProtocol>>,
        EitherUpgrade<SendWrapper<L::OutboundProtocol>, SendWrapper<R::OutboundProtocol>>,
        Either<L::InboundOpenInfo, R::InboundOpenInfo>,
        Either<L::OutboundOpenInfo, R::OutboundOpenInfo>,
    >
where
    L: ConnectionHandler,
    R: ConnectionHandler,
{}

but get that L and R are not constrained. I wonder if #3085 (comment) would have changed that.

Copy link
Contributor

Choose a reason for hiding this comment

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

I was thinking something like e3480d2. It doesn't compile yet but maybe you can make it work!

Copy link
Member Author

Choose a reason for hiding this comment

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

thanks for the lead Thomas, managed to make it work. Used Either::Left for AddressChange instead of the Result as it seemed more semantically accurate in the sense that it's not err, it just doesn't matter if it's either Left or Right for that variant, cause when matching on on_connection_event we still have the Either::Right . Ptal and see if you agree.

Copy link
Contributor

Choose a reason for hiding this comment

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

thanks for the lead Thomas, managed to make it work. Used Either::Left for AddressChange instead of the Result as it seemed more semantically accurate in the sense that it's not err, it just doesn't matter if it's either Left or Right for that variant, cause when matching on on_connection_event we still have the Either::Right . Ptal and see if you agree.

Yeah I wasn't sure about that one. I think one could argue it is an error because we couldn't unambiguously transpose it. Can we make it work with Result or is moving to Either::Left essential?

Alternatively, we could wrap it in another Either but that is a bit weird. If possible, I'd prefer the Result return type and some documentation on why it is necessary.

Copy link
Member Author

Choose a reason for hiding this comment

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

no you are right, documenting it informing that an Err can be because AddressChange isn't transposable makes sense to me, updated it :)

@@ -165,60 +169,72 @@ where
>,
) {
match (info, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here, I think we could make use of the same mapping function from above here.

Copy link
Member Author

Choose a reason for hiding this comment

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

Addressed, see if that's what you were expecting Thomas

Copy link
Member

@mxinden mxinden left a comment

Choose a reason for hiding this comment

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

Thanks for tackling this.

swarm-derive/src/lib.rs Show resolved Hide resolved
Comment on lines -162 to +163
fn on_swarm_event(&mut self, _event: FromSwarm<Self::ConnectionHandler>) {}
fn on_swarm_event(&mut self, event: FromSwarm<Self::ConnectionHandler>);
Copy link
Member

Choose a reason for hiding this comment

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

👍

@@ -367,35 +366,47 @@ where
TInboundSubstreamHandler::upgrade(())
}

fn inject_fully_negotiated_inbound(
fn on_connection_event(
Copy link
Member Author

Choose a reason for hiding this comment

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

this was missed in the previous #3085 sorry, should I add a new changelog entry CC @mxinden? (there was already one in the previous version mentioning the replacement of the methods for Handler)

Copy link
Member

Choose a reason for hiding this comment

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

I don't think this change is breaking, right? Thus advocating for no changelog.

On a related note, shouldn't our CI have caught this? Shouldn't this have generated a deprecation warning and thus shouldn't CI have failed? Can you investigate this @jxs?

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah this isn't a breaking change afaik, as they are only called by the Behaviour

On a related note, shouldn't our CI have caught this? Shouldn't this have generated a deprecation warning and thus shouldn't CI have failed?

good point, cargo doesn't trigger deprecation warning on the implementation, only on the invocation IRC, do we have any code triggering calls to the methods?

#[allow(deprecated)]
handler.inject_fully_negotiated_outbound(output, info)
(Either::Left(handler), EitherOutput::First(output), Either::Left(info)) => {
handler.on_connection_event(ConnectionEvent::FullyNegotiatedOutbound(
Copy link
Member Author

Choose a reason for hiding this comment

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

yeah, that would be great. I tried:

impl<'a, R, L>
    ConnectionEvent<
        'a,
        EitherUpgrade<SendWrapper<L::InboundProtocol>, SendWrapper<R::InboundProtocol>>,
        EitherUpgrade<SendWrapper<L::OutboundProtocol>, SendWrapper<R::OutboundProtocol>>,
        Either<L::InboundOpenInfo, R::InboundOpenInfo>,
        Either<L::OutboundOpenInfo, R::OutboundOpenInfo>,
    >
where
    L: ConnectionHandler,
    R: ConnectionHandler,
{}

but get that L and R are not constrained. I wonder if #3085 (comment) would have changed that.

swarm-derive/src/lib.rs Show resolved Hide resolved
swarm/src/handler.rs Show resolved Hide resolved
Copy link
Member

@mxinden mxinden left a comment

Choose a reason for hiding this comment

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

Thanks for the follow-ups.

@@ -367,35 +366,47 @@ where
TInboundSubstreamHandler::upgrade(())
}

fn inject_fully_negotiated_inbound(
fn on_connection_event(
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this change is breaking, right? Thus advocating for no changelog.

On a related note, shouldn't our CI have caught this? Shouldn't this have generated a deprecation warning and thus shouldn't CI have failed? Can you investigate this @jxs?

Comment on lines 3 to 4
- Replace `NetworkBehaviour` Derive macro deprecated `inject_*` method implementations
with the new `on_swarm_event` and `on_connection_handler_event`.
Copy link
Member

Choose a reason for hiding this comment

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

This entry was previously mistakenly in v0.31.0, right? I.e. we did not actually move to the on_ methods in swarm-derive in v0.31.0 as otherwise our non-breaking-change hack would not have worked, correct?

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah exactly, thanks for referring this Max.

Copy link
Member

@mxinden mxinden left a comment

Choose a reason for hiding this comment

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

Please trigger mergify once the above discussion with @thomaseizinger is resolved.

@mergify
Copy link
Contributor

mergify bot commented Dec 22, 2022

This pull request has merge conflicts. Could you please resolve them @jxs? 🙏

for ConnectionEvent and DialUpgradeError, to help when matching on them
for Either and Select.
S1OOI: Send + 'static,
S2OOI: Send + 'static,
{
fn transpose(self) -> Either<DialUpgradeError<S1OOI, S1OP>, DialUpgradeError<S2OOI, S2OP>> {
Copy link
Contributor

Choose a reason for hiding this comment

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

I like that you split this out. I actually think it makes sense to split this out for all structs of ConnectionEvent. Can we reuse this as part of implementing the bigger transpose function?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, thanks :D but I did it because in some variants like ListenUpgradeError or AddressChange transpose doesn't win us anything as we have to call it for both Select variants. I updated the code implementing for the variants where it makes sense, ptal Thomas and see if it makes sense to you.

@mergify
Copy link
Contributor

mergify bot commented Dec 23, 2022

This pull request has merge conflicts. Could you please resolve them @jxs? 🙏

for the remaining ConnectionEvents that is useful to implement on.
Comment on lines 121 to 126
ConnectionEvent::FullyNegotiatedInbound(FullyNegotiatedInbound {
protocol: EitherOutput::First(protocol),
info: Either::Left(info),
}) => Ok(Either::Left(ConnectionEvent::FullyNegotiatedInbound(
FullyNegotiatedInbound { protocol, info },
))),
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
ConnectionEvent::FullyNegotiatedInbound(FullyNegotiatedInbound {
protocol: EitherOutput::First(protocol),
info: Either::Left(info),
}) => Ok(Either::Left(ConnectionEvent::FullyNegotiatedInbound(
FullyNegotiatedInbound { protocol, info },
))),
ConnectionEvent::FullyNegotiatedInbound(inner) => Ok(inner.transpose()),

Does this work? Or do we have to call .map on it again or something?

It would be cool if we can express this transpose function somehow through the smaller ones.

Copy link
Member Author

Choose a reason for hiding this comment

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

It doesn't because Select's implementation uses SelectUpgrade whereas Either uses EitherUpgrade, do you have any idea how can we combine them in transpose? :P

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we can combine them for select and either because those are fundamentally different.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, one of them is using EitherOutput which we need because Either doesn't implement AsyncRead + AsyncWrite.

See #2650.

@mergify
Copy link
Contributor

mergify bot commented Jan 2, 2023

This pull request has merge conflicts. Could you please resolve them @jxs? 🙏

@jxs
Copy link
Member Author

jxs commented Jan 5, 2023

@thomaseizinger submitted #3307 which started as fork from this one and also addresses some of the conversations here. Can we merge this one and continue there? I can also open an issue to address potential unresolved conversations.

Copy link
Contributor

@thomaseizinger thomaseizinger left a comment

Choose a reason for hiding this comment

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

A few more comments, overall looks good to me!

@@ -7,12 +7,18 @@

- Add `estblished_in` to `SwarmEvent::ConnectionEstablished`. See [PR 3134].

- Remove deprecated `inject_*` methods from `NetworkBehaviour` and `ConnectionHandler`.
see [PR 3260].
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
see [PR 3260].
see [PR 3264].

Wrong issue reference :)

Comment on lines 121 to 126
ConnectionEvent::FullyNegotiatedInbound(FullyNegotiatedInbound {
protocol: EitherOutput::First(protocol),
info: Either::Left(info),
}) => Ok(Either::Left(ConnectionEvent::FullyNegotiatedInbound(
FullyNegotiatedInbound { protocol, info },
))),
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we can combine them for select and either because those are fundamentally different.

Comment on lines 121 to 126
ConnectionEvent::FullyNegotiatedInbound(FullyNegotiatedInbound {
protocol: EitherOutput::First(protocol),
info: Either::Left(info),
}) => Ok(Either::Left(ConnectionEvent::FullyNegotiatedInbound(
FullyNegotiatedInbound { protocol, info },
))),
Copy link
Contributor

Choose a reason for hiding this comment

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

Also, one of them is using EitherOutput which we need because Either doesn't implement AsyncRead + AsyncWrite.

See #2650.

Comment on lines +441 to 480
match fully_negotiated_outbound.transpose() {
Either::Left(f) => self
.proto1
.on_connection_event(ConnectionEvent::FullyNegotiatedOutbound(f)),
Either::Right(f) => self
.proto2
.on_connection_event(ConnectionEvent::FullyNegotiatedOutbound(f)),
}
}
ConnectionEvent::FullyNegotiatedInbound(fully_negotiated_inbound) => {
self.on_fully_negotiated_inbound(fully_negotiated_inbound)
match fully_negotiated_inbound.transpose() {
Either::Left(f) => self
.proto1
.on_connection_event(ConnectionEvent::FullyNegotiatedInbound(f)),
Either::Right(f) => self
.proto2
.on_connection_event(ConnectionEvent::FullyNegotiatedInbound(f)),
}
}
ConnectionEvent::AddressChange(address) => {
#[allow(deprecated)]
self.proto1.inject_address_change(address.new_address);
#[allow(deprecated)]
self.proto2.inject_address_change(address.new_address)
self.proto1
.on_connection_event(ConnectionEvent::AddressChange(AddressChange {
new_address: address.new_address,
}));

self.proto2
.on_connection_event(ConnectionEvent::AddressChange(AddressChange {
new_address: address.new_address,
}));
}
ConnectionEvent::DialUpgradeError(dial_upgrade_error) => {
self.on_dial_upgrade_error(dial_upgrade_error)
match dial_upgrade_error.transpose() {
Either::Left(err) => self
.proto1
.on_connection_event(ConnectionEvent::DialUpgradeError(err)),
Either::Right(err) => self
.proto2
.on_connection_event(ConnectionEvent::DialUpgradeError(err)),
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if it would be better to do it like this for the either::Handler as well? i.e. only transpose the inner type instead of the entire event and matching on the tuple.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah you are right Thomas, you had already mentioned before sorry it slipped me. It makes sense cause then we don't need Err for AddressChange. Updated ptal!

do it per variant instead of on the ConnectionEvent itself, so that we
no longer need the Err on the case of AddressChange.
Copy link
Contributor

@thomaseizinger thomaseizinger left a comment

Choose a reason for hiding this comment

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

LGTM

Nice to see it being a negative diff!

@mergify mergify bot merged commit 4c65c7d into libp2p:master Jan 12, 2023
mergify bot pushed a commit that referenced this pull request Jan 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants