[dashboard] Stream job log responses - #65173
Conversation
There was a problem hiding this comment.
Code Review
This pull request implements log streaming for Ray dashboard jobs, transitioning from loading full logs into memory to streaming them in bounded chunks. It introduces chunked log reading in JobLogStorageClient, updates the job agent and head to support StreamResponse, and adds corresponding unit tests. The review feedback suggests enhancing robustness against encoding issues by explicitly specifying encoding="utf-8" (and errors="replace" when reading) both in the log storage client and the test suite to prevent crashes on non-UTF-8 characters or locales.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0ca9a44f13
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Code Review
This pull request implements log streaming for Ray jobs by transitioning from fetching full log payloads to streaming logs in 64KB chunks using aiohttp's StreamResponse. It updates the job agent, job head, and log storage client to support chunked reading and streaming, while also adding robust error handling for streaming cancellations. The feedback suggests two key improvements: first, using the public response.prepared property instead of the internal req.writer.output_size to check if a response has started; second, adding defensive checks when accessing the request writer in the decorator to prevent potential AttributeError or IndexError during testing.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b3e66f97b4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
Reviewed by Cursor Bugbot for commit 4f35c0e. Configure here.
|
Buildkite #71276 failed in an unrelated core test shard, not in dashboard job tests.
This points to timing/resource flakiness in the reference-counting test rather than a regression from this PR. Recommended next step: retry the failed premerge job; no code change is indicated. |
eaacdcc to
a7536c2
Compare
Read and forward job log responses in bounded chunks so full-log API requests do not require dashboard processes to materialize whole logs. Preserve the existing JSON response and SDK behavior. Signed-off-by: bvolpato <brunocvcunha@gmail.com>
Abort responses when log streaming fails after headers are sent, while preserving normal 500 responses before streaming starts. Decode log files as UTF-8 with replacement and cover both behaviors. Signed-off-by: Bruno Volpato <brunocvcunha@gmail.com>
Let post-prepare failures pass through both dashboard route wrappers so aiohttp aborts incomplete streams. Exercise the bound production route path in the regression test. Signed-off-by: Bruno Volpato <brunocvcunha@gmail.com>
Preserve existing route-table behavior for direct test invocations without request arguments while keeping post-prepare stream failures unhandled. Signed-off-by: Bruno Volpato <brunocvcunha@gmail.com>
Keep first-read, response setup, streaming, and cleanup under one error boundary. Preserve normal pre-prepare failures, abort started responses, and close file-backed generators on every exit. Signed-off-by: Bruno Volpato <brunocvcunha@gmail.com>
Signed-off-by: Bruno Volpato <brunocvcunha@gmail.com>
a7536c2 to
98fd6d4
Compare

Description
Full job-log requests currently read the entire driver log into memory, serialize it in the job agent, deserialize and serialize it again in JobHead, then buffer it once more in the dashboard subprocess proxy. Large or concurrent requests can exhaust dashboard memory.
This change reads log files in 64 KiB chunks, incrementally JSON-escapes them, and streams the response through the job agent, JobHead, and parent dashboard proxy with backpressure. The public application/json response remains {logs: string}, so JobSubmissionClient.get_job_logs() keeps returning complete logs. Client-side memory remains proportional to returned logs because that stable SDK method returns one string.
Related issues
Fixes #28336.
Duplicate-work check: no open PR implements request-time streaming. Closed PR #61537 capped and truncated large responses; this approach preserves complete output. Open PR #65006 rotates on-disk driver logs and is complementary rather than duplicative. I described these differences on #28336 before opening this draft.
Additional information
Testing:
AI assistance was used.