ClientConnectionImpl: Delay setTransportSocketCallbacks() until end of the constructor.#5307
Conversation
…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>
mattklein123
left a comment
There was a problem hiding this comment.
One question and also need to fix format. Thank you!
/wait
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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...
614e40e to
737c794
Compare
|
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>
239f56f to
7b6e210
Compare
mattklein123
left a comment
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
nit: You mean make_unique?
| 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. |
| // 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); |
There was a problem hiding this comment.
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?
| public TransportSocketCallbacks, | ||
| protected Logger::Loggable<Logger::Id::connection> { | ||
| public: | ||
| protected: |
There was a problem hiding this comment.
nit: unless it can't be done, please move so the class is defined from public -> protected -> private. Same below.
There was a problem hiding this comment.
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. |
| */ | ||
| class ConfigValidateConnection : public Network::ClientConnectionImpl { | ||
| public: | ||
| private: |
This doesn't sound right really, from interface level |
This change seems fine to me, but fine to defer to @lizan and @jrajahalme to discuss an alternate solution. |
|
@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 I don't really care how the "construction notification" is done, but piggy-backing it to the |
|
@lizan @mattklein123 I just realized that depending on how |
|
@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. |
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