Repository navigation
THRIFT-6436: Avoid repeated bytes concatenation in Python readAll - #4028
OneSizeFitsQuorum wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
3 open issues
What changed in this PR
Improves Python client transport performance by making TTransportBase.readAll accumulate chunks and join() once, avoiding repeated bytes concatenation for fragmented reads.
Changes:
- Refactor
TTransportBase.readAllto collect read chunks in a list andb''.join()at the end. - Add regression tests for
readAllbehavior across fragmentation, EOF, exceptions, and framed payloads. - Add a loopback RPC benchmark to compare baseline vs updated
readAllbehavior and record socket read fragmentation.
| File | Description |
|---|---|
| lib/py/src/transport/TTransport.py | Switch readAll from incremental bytes concatenation to list accumulation + join for better performance on fragmented reads. |
| lib/py/test/thrift_transport.py | Add regression tests and a small fragmented transport helper to verify readAll semantics. |
| lib/py/test/benchmark_readall.py | Add a standalone benchmark to measure before/after readAll behavior over a framed RPC on loopback TCP. |
Review effort: Lite
fac7037 to
c4ceabf
Compare
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
6 open issues
test_benchmark_readall.py(andbenchmark_readall.py) uses Python 3-only stdlib features (e.g.,… · Newtest_benchmark_readall.py(andbenchmark_readall.py) uses Python 3-only stdlib features (e.g.,… · Newstruct.packis used in the new test but there is noimport structshown in the updated imports.…server.kill()is not available on older Python 3 versions (it was added after the earliest 3.x… · Newspec_from_file_location()can returnNone, andspec.loadercan beNone(e.g., if… The benchmark assumes only the 4-byte frame header usesreadAll(4)and treats any `readAll(sz <=…
Review effort: Lite
c4ceabf to
a56da09
Compare
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
7 open issues
test_benchmark_readall.py(andbenchmark_readall.py) uses Python 3-only stdlib features (e.g.,…test_benchmark_readall.py(andbenchmark_readall.py) uses Python 3-only stdlib features (e.g.,…struct.packis used in the new test but there is noimport structshown in the updated imports.… This changes the accepted element types inreadAll:b''.join(...)accepts general bytes-like… · Newserver.kill()is not available on older Python 3 versions (it was added after the earliest 3.x…spec_from_file_location()can returnNone, andspec.loadercan beNone(e.g., if… The benchmark assumes only the 4-byte frame header usesreadAll(4)and treats any `readAll(sz <=…
Review effort: Lite
a56da09 to
443b9a7
Compare
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
10 open issues
struct.packis used but this diff doesn't add animport structin the module imports shown… · Newtest_benchmark_readall.py(andbenchmark_readall.py) uses Python 3-only stdlib features (e.g.,…test_benchmark_readall.py(andbenchmark_readall.py) uses Python 3-only stdlib features (e.g.,…struct.packis used in the new test but there is noimport structshown in the updated imports.… This changes the accepted element types inreadAll:b''.join(...)accepts general bytes-like…server.kill()is not available on older Python 3 versions (it was added after the earliest 3.x…spec_from_file_location()can returnNone, andspec.loadercan beNone(e.g., if… The benchmark assumes only the 4-byte frame header usesreadAll(4)and treats any `readAll(sz <=… The new comment states a behavioral requirement about mutation, butread()in Python transports… · New On EOF (chunkLen == 0), the code appends an empty chunk tobuffand then immediately raises.… · New
Review effort: Lite
443b9a7 to
a17e73f
Compare
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
2 open issues
10 resolved since last review
struct.packis used but this diff doesn't add animport structin the module imports shown…test_benchmark_readall.py(andbenchmark_readall.py) uses Python 3-only stdlib features (e.g.,…test_benchmark_readall.py(andbenchmark_readall.py) uses Python 3-only stdlib features (e.g.,…struct.packis used in the new test but there is noimport structshown in the updated imports.… This changes the accepted element types inreadAll:b''.join(...)accepts general bytes-like…server.kill()is not available on older Python 3 versions (it was added after the earliest 3.x…spec_from_file_location()can returnNone, andspec.loadercan beNone(e.g., if… The benchmark assumes only the 4-byte frame header usesreadAll(4)and treats any `readAll(sz <=… On EOF (chunkLen == 0), the code appends an empty chunk tobuffand then immediately raises.… The new comment states a behavioral requirement about mutation, butread()in Python transports…
Review effort: Lite
Client: py Collect readAll chunks and join once, preserving short-read and EOF behavior. Add regression tests for fragmented reads, read sizes, EOF and exception propagation. Generated-by: OpenAI Codex (GPT-6)
a17e73f to
c251c26
Compare
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
No open issues 🎉
2 resolved since last review
Review effort: Lite



JIRA: https://issues.apache.org/jira/browse/THRIFT-6436
Client: py
TTransportBase.readAllrepeatedly copies the accumulated bytes when a read completes through multiple short reads. Collect chunks and join them once instead. A short inline comment explains why chunks are joined once.The patch is limited to the accumulation loop and seven regression tests in the existing transport test file. They cover fragmented and single reads, remaining request sizes, nonpositive sizes, EOF, exception propagation, consecutive reads, and a fragmented frame.
Local performance validation
A separate Python
TSimpleServerprocess returned a prebuilt 30 MiB binary payload over loopback TCP, usingTBinaryProtocolandTFramedTransport. Only the client'sreadAllimplementation differed. Each implementation had seven alternating rounds of three measured RPCs, with one warm-up per round. Values below are medians over 21 RPCs; timing excludes connection setup and payload verification. Frame/string limits were explicitly configured for the large test response.Environment: CPython 3.10.12, Linux 6.8.0-136-generic x86_64, Intel Xeon Platinum 8362 @ 2.80 GHz, eight logical CPUs visible. Baseline: db8caa7.
Unrestricted frame-body read counts ranged from 11–14 before and 136–437 after, so fragmentation was not identical. The explicitly controlled 64 KiB case used exactly 481 body reads for both implementations. These are local synthetic-service measurements, not HBase throughput results or predictions for other deployments. The RPC harness and raw results remain local.
Standalone reproduction of fragmented-read cost
This is an in-memory check of the accumulation cost, independent of the TCP measurements above. After checking out this PR:
Validation
The seven new regression tests were added and run against the original implementation before applying the runtime change.
All 14 transport tests passed after the change, along with the local TCP A/B measurements above.
All 26 Python-specific CI checks passed for the final commit, covering Python 3.10–3.14 on Linux and the macOS matrix, plus Python static analysis.
flake8 --max-line-length=100,codespellandgit diff --checkpassed for the final patch.make styleis unavailable in this unconfigured checkout because there is no root Makefile.CI environment note: the Smalltalk setup job fails while downloading the Pharo image (
curlexit 7), before its tests run. Repository administrator permissions are required to rerun that job.Generated-by: OpenAI Codex (GPT-6)