Skip to content

ClientConnectionImpl: Delay setTransportSocketCallbacks() until end of the constructor.#5307

Closed
jrajahalme wants to merge 3 commits intoenvoyproxy:masterfrom
jrajahalme:fully-construct-connection-before-callbacks
Closed

ClientConnectionImpl: Delay setTransportSocketCallbacks() until end of the constructor.#5307
jrajahalme wants to merge 3 commits intoenvoyproxy:masterfrom
jrajahalme:fully-construct-connection-before-callbacks

Conversation

@jrajahalme
Copy link
Copy Markdown
Contributor

@jrajahalme jrajahalme commented Dec 14, 2018

ConnectionImpl already calls 'setTransportSocketCallbacks()' at the
end of construction, so that when called the transport socket sees the
Connection in a fully constructed state.

In the case of the ClientConnectionImpl the semantics are less clear,
as the setTransportSocketCallbacks() is called in the middle of the
construction process. This commit changes this so that for derived
classes the setTransportSocketCallbacks() is called at the end of the
derived class construction.

The motivation for this change comes from a TransportSocket extension
that relies on all socket options on client connections being set at
the time when setTransportSocketCallbacks() is called.

Risk Level: Low
Signed-off-by: Jarno Rajahalme jarno@covalent.io

…f the constructor.

ConnectionImpl already calls 'setTransportSocketCallbacks()' at the
end of construction, so that when called the transport socket sees the
Connection in a fully constructed state.

In the case of the ClientConnectionImpl the semantics are less clear,
as the setTransportSocketCallbacks() is called in the middle of the
construction process. This commit changes this so that for derived
classes the setTransportSocketCallbacks() is called at the end of the
derived class construction. Currently this is accomplished by only
calling the setTransportSocketCallbacks() in ConnectionImpl
constructor if the 'connected' parameter is passed in as 'true', as
this is always the case for server connections, while the
ClientConnectionImpl constructor passes this parameter as 'false'.

The motivation for this change comes from a TransportSocket extension
that relies on all socket options on client connections being set at
the time when setTransportSocketCallbacks() is called.

Signed-off-by: Jarno Rajahalme <jarno@covalent.io>
Copy link
Copy Markdown
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

One question and also need to fix format. Thank you!

/wait

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is pretty fragile IMO. WDYT about making the constructor private and then have a static factory function that does the right thing for the various places that need to construct a connection? Would that be possible?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That would be a bit more "boilerplate" but would be not fragile at all, I'll give it a go. And sorry about the format thing, getting rusty...

@mattklein123 mattklein123 self-assigned this Dec 14, 2018
@jrajahalme jrajahalme force-pushed the fully-construct-connection-before-callbacks branch from 614e40e to 737c794 Compare December 14, 2018 23:51
@repokitteh-read-only
Copy link
Copy Markdown

🙀 Error while processing event:

evaluation error
error: context deadline exceeded
🐱

Caused by: #5307 was unlabeled by repokitteh[bot].

see: more, trace.

@jrajahalme
Copy link
Copy Markdown
Contributor Author

Took the liberty to force push as the implementation is now completely different.

…nstructor being static.

Now that Network::ClientConnectionImpl constructor is protected,
ConfigValidateConnection also needs a static create() function.

Signed-off-by: Jarno Rajahalme <jarno@covalent.io>
Use Network::ClientConnectionImpl::createClientConnection() instead of the protected constructor.

Signed-off-by: Jarno Rajahalme <jarno@covalent.io>
@jrajahalme jrajahalme force-pushed the fully-construct-connection-before-callbacks branch from 239f56f to 7b6e210 Compare December 16, 2018 01:13
@repokitteh-read-only
Copy link
Copy Markdown

🙀 Error while processing event:

evaluation error
error: context deadline exceeded
🐱

Caused by: #5307 was unlabeled by repokitteh[bot].

see: more, trace.

Copy link
Copy Markdown
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

Thanks a ton, this is much cleaner now. Few comments.

/wait

std::unique_ptr<ConnectionImpl>
ConnectionImpl::createServerConnection(Event::Dispatcher& dispatcher, ConnectionSocketPtr&& socket,
TransportSocketPtr&& transport_socket) {
// make_shared<> requires a public constructor so we can't use it here.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: You mean make_unique?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, will fix.

const Address::InstanceConstSharedPtr& source_address,
Network::TransportSocketPtr&& transport_socket,
const Network::ConnectionSocket::OptionsSharedPtr& options) {
// make_shared<> requires a public constructor so we can't use it here.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

make_unique?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Right.

// make_shared<> requires a public constructor so we can't use it here.
std::unique_ptr<Network::ConnectionImpl> conn(new Network::ConnectionImpl(
dispatcher, std::move(socket), std::move(transport_socket), true));
conn->transport_socket_->setTransportSocketCallbacks(*conn);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you add a comment here and below (or just refer one to the other) of why we need to do this for future readers?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Will do.

public TransportSocketCallbacks,
protected Logger::Loggable<Logger::Id::connection> {
public:
protected:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: unless it can't be done, please move so the class is defined from public -> protected -> private. Same below.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Should be doable.

const Address::InstanceConstSharedPtr& source_address,
Network::TransportSocketPtr&& transport_socket,
const Network::ConnectionSocket::OptionsSharedPtr& options) {
// make_shared<> requires a public constructor so we can't use it here.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

make_unique?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ditto.

*/
class ConfigValidateConnection : public Network::ClientConnectionImpl {
public:
private:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

order

@lizan
Copy link
Copy Markdown
Member

lizan commented Dec 16, 2018

The motivation for this change comes from a TransportSocket extension
that relies on all socket options on client connections being set at
the time when setTransportSocketCallbacks() is called.

This doesn't sound right really, from interface level setTransportSocketCallbacks() isn't expected to do anything else than keeping/propagating the reference of transport socket callbacks. If onConnected doesn't fit your use case, I think we can add another hook point for that.

@mattklein123
Copy link
Copy Markdown
Member

This doesn't sound right really, from interface level setTransportSocketCallbacks() isn't expected to do anything else than keeping/propagating the reference of transport socket callbacks. If onConnected doesn't fit your use case, I think we can add another hook point for that.

This change seems fine to me, but fine to defer to @lizan and @jrajahalme to discuss an alternate solution.

@jrajahalme
Copy link
Copy Markdown
Contributor Author

@lizan It seems reasonable to me to expect that, in general, the callbacks, when called after being set, will get the results as if the underlying objects have been fully constructed. However, it may be that what I need should be done by some other means when the IoHandle and TransportSocket abstractions are fully developed. Specifically, in my case, a specialized TransportSocket needs to know when the ClientConnectionImpl has been fully constructed (including any socket options being set) before the client connection can get to the connected state. I.e., my transport socket implementation determines when a connection has been made in an I/O model where each connection does not have a unique file descriptor, but a virtual "I/O handle".

I don't really care how the "construction notification" is done, but piggy-backing it to the setTransportSocketCallbacks() felt like a natural extension of the semantics of it. It was already true for ConnectionImpl and seemed like a reasonable thing to do also for ClientConnectionImpl. Would you want so see a connectionConstructed() callback being added instead?

@jrajahalme
Copy link
Copy Markdown
Contributor Author

@lizan @mattklein123 I just realized that depending on how IP_TRANSPARENT PR (#5255) lands, I might not need this, so I'm OK parking this PR for a while.

@mattklein123
Copy link
Copy Markdown
Member

@jrajahalme OK I will just close this for now. We can reopen if needed. I'm going to try to review all of the transparent stuff some time today.

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