A small and lean coroutine library for Envoy#46283
Conversation
Signed-off-by: Peng Gao <pengg@google.com>
Signed-off-by: Peng Gao <pengg@google.com>
Signed-off-by: Peng Gao <pengg@google.com>
|
We are going to bump LLVM to 22 (from 18), hopefully soon. Is this bump somehow going to affect - positively or negatively - this effort? |
Should be a positive change - LLVM 22 further matures C++20 support, while starting to bring in C++26. This PR is only using C++20 features, which are already well supported in LLVM 18. |
botengyao
left a comment
There was a problem hiding this comment.
thanks @penguingao! flushing some questions.
also would love get @kyessenov @ravenblackx @ggreenway 's input on this direction.
Signed-off-by: Peng Gao <pengg@google.com>
penguingao
left a comment
There was a problem hiding this comment.
Thanks @botengyao for the review!
I'd like to also clarify that this library is to incrementally allow new code to be written in coroutine. It doesn't aim at rewriting core Envoy.
The main reason we introduced a launch() with a done callback is to make it easy to call into a coroutine from normal Envoy methods.
That said, if we do find coroutine being a successful attempt, we can always use it to improve existing things incrementally.
Happy to discuss and clarify things. |
|
/retest |
Signed-off-by: Peng Gao <pengg@google.com>
botengyao
left a comment
There was a problem hiding this comment.
here is another pass, my take here is we can check in this lib to experiment.
/wait
Signed-off-by: Peng Gao <pengg@google.com>
…nch(); add a micro benchmark Signed-off-by: Peng Gao <pengg@google.com>
Signed-off-by: Peng Gao <pengg@google.com>
Signed-off-by: Peng Gao <pengg@google.com>
|
I also added a microbenchmark to make sure that coroutine's performance is comparable. It's an echo server that does at most one read and one write per epoll loop. Realistic because we don't want to hold the epoll for a single call stack. The test send 1MB of data through the echo server, and we vary on reader and writer bottleneck to simulate real world. We try different buffer and batch sizes. On my dev VM, I ran the benchmark with The table here summarizes the relative CPU usage for sending 1MB over different conditions. |
Signed-off-by: Peng Gao <pengg@google.com>
Signed-off-by: Peng Gao <pengg@google.com>
Signed-off-by: Peng Gao <pengg@google.com>
Signed-off-by: Peng Gao <pengg@google.com>
Commit Message: A minimum library to support coroutine in Envoy, integrating with Envoy's dispatcher and siloed architecture.
C++20 brings language / compiler support of coroutine, but it doesn't come with STL support, due to the lack of standard runtime / event loop in the language. There are a few libraries that have been considered before writing this library, but they either bring in heavy dependencies or a foreign event loop. Given that Envoy's code is mostly siloed, there is no requirement for the library to worry about locking. This enables a relatively small and lean library like this PR. For any existing library to work with Envoy, custom integration with Envoy's Dispatcher is required any way, which is of similar effort, but brings in more dependencies into Envoy.
C++26 will bring STL support, so we can get rid of this library when it happens. https://cppreference.com/cpp/execution / std::execution::task
The gist of coroutine is that it allows a function / method to suspend execution once
co_awaitorco_yieldis encountered, and return the thread's control to the outer most caller. The inner most function that's suspended can later be resumed once certain condition is met. This enables sequatial-style code for asynchronous operations, which is generally more readable.This PR includes the following utilities:
Task<>template that is the return type of all Envoy coroutines;LeafAwaitable<>template that allows coroutines toco_awaiton callbacks;launch()method to allow callback to call into coroutine and receive the result via a done callback;This allows writing pieces of Envoy code in coroutine when appropriate without a major refactor.
I used AI to generate some of the code, and I fully reviewed and understood the code.
Additional Description: https://gist.github.com/penguingao/21b22bec816be0c833c4d92c866a89cf contains the motivation and some design choices.
Risk Level: low - new unused library
Testing: unit tests
Docs Changes: n/a
Release Notes: n/a
Platform Specific Features: n/a