-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Title:
Do not send empty data chunk with end_of_stream FALSE to the ext_proc server
Description:
-
Currently, Envoy ext_proc filter is sending whatever data receives from the filter chain, and create a gRPC message and send that data to the ext_proc server. This means even a data chunk's size is 0, and end_of_stream = false, it will be sent to the ext_proc server.
-
Such zero size data chunk with end_of_stream = false does not carry any useful information, thus such gRPC messages to the ext_proc server are a totally waste to Envoy and the ext_proc server.
-
In normal situations, it's rare for Envoy codec to send an empty data chunk with end_of_stream = false to the HTTP filter chain. Thus the above problem is not a big deal. Note, zero sized data chunk with end_of_stream = true is meaningful and not in the scope of this discussion.
-
However, with Envoy ext_proc STREAMED mode, the data is moved to a local buffer, and an empty chunk with end_of_stream=false is sent down the filter chain (Seeking proposals for how to implement STREAMING body mode in ext_proc #16760. Such behavior is leveraged to the ext_proc FULL_DUPLEX_STREAMED mode.
-
With 4), also if there are two ext_proc filters configured in the HTTP filter chain, it is pretty routine to see empty data chunks with end_of_stream=false are observed by the 2nd ext_proc filter, as the 1st ext_proc filter created such data chunks.
-
There is no functional issue observed with this issue. However, we should optimize to avoid such kind of wasted gRPC messages.
Solution:
Option 1: For STREAMED mode, after move the data into ext_proc local buffer, it probably can just stop iteration(return StopIterationNoBuffer:
| return Http::FilterDataStatus::StopIterationNoBuffer; |
This option is cleaner, but it has some ext_proc state machine change, so a little bit risky. Also, needs to figure out why existing behavior is sending an empty data chunk down the filter chain.
Option 2: Envoy ext_proc can add a check : if chunk data size is zero, and end_of_stream == false, do not send it to the ext_proc server. This does not avoid zero chunk data + eos_false to the remain filter chain, but avoided it being sent to the ext_proc server.
This option 2 is simple and almost no risk at all.