Full picture of in memory listener and connection#13361
Full picture of in memory listener and connection#13361lambdai wants to merge 45 commits intoenvoyproxy:masterfrom
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 |
alyssawilk
left a comment
There was a problem hiding this comment.
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.
Maybe explain what binding is in internal address context?
There was a problem hiding this comment.
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.
did you mean this to be static? If so fix and test?
There was a problem hiding this comment.
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.
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.
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.
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.
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.
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.
Also some of these are good to keep as debug logs, though not MISC_LOG
There was a problem hiding this comment.
Absolutely. Will assign reasonable logger and level in the split PRs
lambdai
left a comment
There was a problem hiding this comment.
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.
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.
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.
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.
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.
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.
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 descriptorin 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...