-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Full picture of in memory listener and connection #13361
Conversation
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
…ernal and Tcp listener Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
Signed-off-by: Yuchen Dai <[email protected]>
@alyssawilk Please ignore the verbose log. I will clean up the log along with individual PRs |
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.
Hey @lambdai, it's really exciting to see progress on this one!
I think the overall structure is fine. My WIP pass comments are to see where we can reduce duplicated code - the auto-close connection I think can be cleaned up and I'm wondering if we can also do some around the ActiveInternal classes.
To get this landed I also think we're going to need to split this up, rather than have one giant PR. I wonder if we can land the BufferedIoSocketHandleImpl with utilitiy classes but minimal changes to core code. WDYT?
* Creates an client internal connection. Does NOT initiate the connection; | ||
* the caller must then call connect() on the returned Network::ClientConnection. | ||
* @param internal_address supplies the internal address to connect to. | ||
* @param local_address supplies an address to bind to or nullptr if no bind is necessary. |
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.
Maybe explain what binding is in internal address context?
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. Will add that listener side connection could obtain the bind local address for debug.
I also want to add here that I want to introduce a generic "socket options" param in the future to deliver more information including "original address" which is supposed to be "ip/port" address raising this internal address.
namespace { | ||
Network::Address::InstanceConstSharedPtr | ||
nextClientAddress(const Network::Address::InstanceConstSharedPtr& server_address) { | ||
uint64_t id = 0; |
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.
did you mean this to be static? If so fix and test?
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.
Ah, yes. It should be static. The local address is well used, only need to guarantee such address is not nullptr.
Look like you are fine with such a debug purpose address :)
for (const auto& [name, _] : internal_listeners_) { | ||
ENVOY_LOG_MISC(debug, "lambdai: p listener {}", name); | ||
} | ||
if (iter == internal_listeners_.end()) { |
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.
hm, I would have expected this in connect(). When we do normal IP style create and connect do we validate before connect?
no strong opinion either way, but if you prefer this maybe comment about where validation is done in include/ ?
Actually I think if you move this work to CONNECT you can skip the entire closingClientConnectionImpl which would be nice clean up
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 reason I want to split ClosingClientConnectionImpl
and ClientConnectionImpl
:
The underlying BufferedIoSocketHandleImpl
is aware of single transition: from "connected" to "disconnected".
If we set up the server connection in connect()
, the client connection need to track "uninitialized" to "connected", "uninitialized" to "fail to connect".
BTW, The model internal connection I am borrowing from "socketpair()"
// Find the internal listener callback. The listener will setup the server connection. | ||
auto iter = internal_listeners_.find(internal_address->asString()); | ||
for (const auto& [name, _] : internal_listeners_) { | ||
ENVOY_LOG_MISC(debug, "lambdai: p listener {}", name); |
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 inclined to do my next pass once you've had a chance to clean these up, and do a sweep to make sure the code is commented.
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.
This PR is adding 3000 lines. Do you think it is realistic to merge this PR without splitting?
If not I prefer to keep the debug purpose log: I will backport the split PRs and see if the sub PRs breaks this overall PR: This PR has quite a few real world integration tests. These integration tests must pass but cannot be put in early sub PRs.
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 think given the complexity it'd be better to split out what we can. It could be that it's just 2-3? As said I think the buffer code would split out pretty easily so let's give that a try and see what's left.
Also w.r.t. logging I think it's fine to leave many of the logs in (all the error corner case logs for example) and just move them from lambdai/LOG_MISC to real logs. It's fine to tackle that as the last step when the big PR is ready for review if you prefer.
if (iter == internal_listeners_.end()) { | ||
ENVOY_LOG_MISC(debug, "lambdai: no valid listener registered for envoy internal address {}", | ||
internal_address->asString()); | ||
return std::make_unique<Network::ClosingClientConnectionImpl>(*this, internal_address, |
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.
Also some of these are good to keep as debug logs, though not MISC_LOG
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.
Absolutely. Will assign reasonable logger and level in the split PRs
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.
Thank you for the review! Let me add comments first
* Creates an client internal connection. Does NOT initiate the connection; | ||
* the caller must then call connect() on the returned Network::ClientConnection. | ||
* @param internal_address supplies the internal address to connect to. | ||
* @param local_address supplies an address to bind to or nullptr if no bind is necessary. |
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. Will add that listener side connection could obtain the bind local address for debug.
I also want to add here that I want to introduce a generic "socket options" param in the future to deliver more information including "original address" which is supposed to be "ip/port" address raising this internal address.
namespace { | ||
Network::Address::InstanceConstSharedPtr | ||
nextClientAddress(const Network::Address::InstanceConstSharedPtr& server_address) { | ||
uint64_t id = 0; |
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.
Ah, yes. It should be static. The local address is well used, only need to guarantee such address is not nullptr.
Look like you are fine with such a debug purpose address :)
// Find the internal listener callback. The listener will setup the server connection. | ||
auto iter = internal_listeners_.find(internal_address->asString()); | ||
for (const auto& [name, _] : internal_listeners_) { | ||
ENVOY_LOG_MISC(debug, "lambdai: p listener {}", name); |
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.
This PR is adding 3000 lines. Do you think it is realistic to merge this PR without splitting?
If not I prefer to keep the debug purpose log: I will backport the split PRs and see if the sub PRs breaks this overall PR: This PR has quite a few real world integration tests. These integration tests must pass but cannot be put in early sub PRs.
for (const auto& [name, _] : internal_listeners_) { | ||
ENVOY_LOG_MISC(debug, "lambdai: p listener {}", name); | ||
} | ||
if (iter == internal_listeners_.end()) { |
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 reason I want to split ClosingClientConnectionImpl
and ClientConnectionImpl
:
The underlying BufferedIoSocketHandleImpl
is aware of single transition: from "connected" to "disconnected".
If we set up the server connection in connect()
, the client connection need to track "uninitialized" to "connected", "uninitialized" to "fail to connect".
BTW, The model internal connection I am borrowing from "socketpair()"
if (iter == internal_listeners_.end()) { | ||
ENVOY_LOG_MISC(debug, "lambdai: no valid listener registered for envoy internal address {}", | ||
internal_address->asString()); | ||
return std::make_unique<Network::ClosingClientConnectionImpl>(*this, internal_address, |
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.
Absolutely. Will assign reasonable logger and level in the split PRs
auto client_io_handle_ = std::make_unique<Network::BufferedIoSocketHandleImpl>(); | ||
auto server_io_handle_ = std::make_unique<Network::BufferedIoSocketHandleImpl>(); |
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.
BufferedIoSocketHandleImpl as extension here?
This pull request has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
This pull request has been automatically closed because it has not had activity in the last 37 days. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
A almost rewrite of #12537
Prototype of #11725
Implementations
Replaced the BufferSource transport socket. So existing transport socket could be supported. Special thank to @florincoras 's work dropping the
file descriptor
in transport sockets and other filters!This is an socket handle which owns a buffer. Think the buffer as the socket buffer in the kernel. This handle should be always created with a peer so that this handle could write to peer's buffer, and notify readable or writable signal along with read/write/shutdown.
Allow register internal listener and target listener when a client connection need to be created
Register internal listener by name and "accept" connection. Currently internal listener could simulate tcp listener but not udp listener.
Past work
Envoy Internal address type is introduced in api: add envoy internal address #12837
A new type of address, or specialize the ip/pipe?[WIP] Envoy Internal connection strawman #12537 Dropped since I force pushed...