Skip to content
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

feat: sse-timing plugin for tracing events #1361

Open
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

jizhuozhi
Copy link
Contributor

@jizhuozhi jizhuozhi commented Oct 2, 2024

Ⅰ. Describe what this PR did

Add sse-timing plugin for tracing timestamp that each event received in higress. An alternative implementation of the server-timing protocol (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing). It's useful to profile AI backend latency which uses event-stream MIME type.

And implemention an EventStream for common SSE(text/event-stream) parsing.

Ⅱ. Does this pull request fix one issue?

None

Ⅲ. Why don't you add test cases (unit test/integration test)?

I'm sorry I don't know how to add WASM testcase, we could discuss in this PR.

Ⅳ. Describe how to verify it

There is a docker-compose.yml in plugin directory, with a go server backend which provides sse response, up it and then just use broswer to open http://localhost:10000, you could see events in dev-tools.

Ⅴ. Special notes for reviews

@jizhuozhi jizhuozhi requested a review from 007gzs as a code owner October 2, 2024 11:02
@codecov-commenter
Copy link

codecov-commenter commented Oct 2, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 43.58%. Comparing base (ef31e09) to head (8dc3b4f).
Report is 157 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1361      +/-   ##
==========================================
+ Coverage   35.91%   43.58%   +7.67%     
==========================================
  Files          69       76       +7     
  Lines       11576    12320     +744     
==========================================
+ Hits         4157     5370    +1213     
+ Misses       7104     6616     -488     
- Partials      315      334      +19     

see 69 files with indirect coverage changes

@johnlanni
Copy link
Collaborator

@jizhuozhi Please fix the CI.

@johnlanni
Copy link
Collaborator

cc @007gzs

@007gzs
Copy link
Collaborator

007gzs commented Oct 6, 2024

Please add e2e test cases. Reference https://github.com/alibaba/higress/tree/main/test/e2e/conformance/tests

@jizhuozhi
Copy link
Contributor Author

Will, I have seen the test-suits in https://github.com/alibaba/higress/tree/main/test/e2e/conformance/tests, it seems just supporting static response assertion as server-timing is streaming injecting dynamic metainfo into response body, and no sse server as upstream (I just found echo-server and echo-body in deployments). Does any solution or example here?

_num_headers: usize,
_end_of_stream: bool,
) -> HeaderAction {
match self.get_http_response_header("Content-Type") {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The E2E test failed because it modifies the body; hence, it is necessary to remove the 'Content-Length' header during the header processing stage.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to text/event-stream MIME type, the origin server should not set Content-Length in response headers, I will change custom-response to support streaming response

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using custom response to simulate responses will definitely add the content-length header. In real scenarios, when using the text/event-stream MIME type, it's not necessarily chunked transfer either; for example, if a proxy does caching in between, the content-length header might also be added. Therefore, the logic should still include compatibility handling and uniformly remove the content-length header.

| headers | array of string | Optional | - | Custom HTTP response headers, keys and values separated by `=` |
| body | string | Optional | - | Custom HTTP response body |
| enable_on_status | array of number | Optional | - | Match original status codes to generate custom responses; if not specified, the original status code is not checked |
| is_stream | bool | Optional | false | If stream response, will not set Content-Length header |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, it is not possible to control whether the content-length header is set, because when the plugin calls sendHTTPResponse, it will callback to the Envoy logic, which automatically adds this header

Copy link
Collaborator

@johnlanni johnlanni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed above, the plugin needs to be compatible with the potential presence of the content-length response header, but modifying the body can lead to inconsistent lengths. Simply removing the content-length response header during the response header phase is sufficient, and Envoy will automatically switch to chunked transfer mode.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants