feat: add streaming endpoint for inference requests - #157
Conversation
Signed-off-by: Dorin Geman <dorin.geman@docker.com>
| m["POST "+inference.InferencePrefix+"/{backend}/_configure"] = s.Configure | ||
| m["POST "+inference.InferencePrefix+"/_configure"] = s.Configure | ||
| m["GET "+inference.InferencePrefix+"/requests"] = s.openAIRecorder.GetRecordsHandler() | ||
| m["GET "+inference.InferencePrefix+"/requests/stream"] = s.openAIRecorder.StreamRequestsHandler() |
There was a problem hiding this comment.
have you considered using same /requests endpoint?and return streams in case of "Content-Type": "text/event-stream",?
There was a problem hiding this comment.
Right, using an Accept: text/event-stream in the GET request might provide an easy differentiator (with no header defaulting to one-shot application/json.
There was a problem hiding this comment.
Ah, it looks like you're already sending that in the CLI, so yeah, that might keep the API a bit cleaner.
There was a problem hiding this comment.
Good idea! Implemented in 6ad7d25. Thanks!
There was a problem hiding this comment.
Pull Request Overview
This PR adds a streaming endpoint for inference requests using Server-Sent Events (SSE) to the OpenAI recorder functionality. The change enables real-time monitoring of requests and responses recorded by the OpenAIRecorder.
Key changes:
- Added SSE streaming support to the existing
/engines/requestsendpoint - Implemented subscriber management for broadcasting new request/response pairs
- Added support for including existing records when subscribing to the stream
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
|
|
||
| // Create subscriber channel. | ||
| subscriberID := fmt.Sprintf("sub_%d", time.Now().UnixNano()) | ||
| ch := make(chan *RequestResponsePair, 100) |
There was a problem hiding this comment.
The buffer size of 100 is a magic number. Consider defining this as a named constant (e.g., subscriberChannelBufferSize) to make the code more maintainable and allow for easier configuration.
Differentiate regular and streaming based on the Accept Header. Signed-off-by: Dorin Geman <dorin.geman@docker.com>
6ad7d25 to
a0ddf2e
Compare
Signed-off-by: Dorin Geman <dorin.geman@docker.com>
There was a problem hiding this comment.
Pull Request Overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
…tion Explains that modelRecords is expected to have size 1 due to how broadcastToSubscribers is called, avoiding the need for a second model config query. Signed-off-by: Dorin Geman <dorin.geman@docker.com>
Signed-off-by: Dorin Geman <dorin.geman@docker.com>
|
@doringeman do you think some of the review comments are worth addressing? If not please resolve. |
Signed-off-by: Dorin Geman <dorin.geman@docker.com>
|
@ericcurtin addressed them in the last 3 commits. Resolved. |
ilopezluna
left a comment
There was a problem hiding this comment.
I added a question, not to change the code, but just to understand the convention.
| allRecords := r.getAllRecords() | ||
| if allRecords == nil { | ||
| // No records found. | ||
| http.Error(w, "No records found", http.StatusNotFound) | ||
| return | ||
| } |
There was a problem hiding this comment.
There’s no need to change it, this is actually the current behavior. I’m just curious whether this is considered idiomatic in Go.
In Java, for example, a getAllRecords() method would return an empty array if no records are found, and the request would still return a 200 status code, which makes sense since the request itself succeeded.
In our case, though, the HTTP status code is being used to reflect business logic: a 404 means "no records found."
This morning, I got confused while debugging because I interpreted the 404 Not Found as if the endpoint itself didn’t exist, rather than simply meaning there were no records.
There was a problem hiding this comment.
Actually you're right, it's more REST idiomatic to return an empty list and 200.
The 404 doesn't really make sense here as the endpoint and the resource exist (although it's empty).
|
|
||
| // Optional: Send existing records first. | ||
| model := req.URL.Query().Get("model") | ||
| if includeExisting := req.URL.Query().Get("include_existing"); includeExisting == "true" { |
Signed-off-by: Dorin Geman <dorin.geman@docker.com>
There was a problem hiding this comment.
Pull Request Overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
Add a streaming endpoint for the requests+responses recorded by the
OpenAIRecorder.You can also interact with it using docker-archive-public/docker.model-cli#151.