GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — feat: Stream Trino offline results via to_arrow_reader by dbbvitor · Pull Request #6897 · feast-dev/feast Conversation
Contributor
What this PR does / why we need it:Adds a default Design note: the fork patch this replaces used Also fixes Retires fork patches Which issue(s) this PR fixes:Closes #6863 (merge after #6896 ) Checks
Testing Strategy
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactionsThe offline server's do_get and do_exchange handlers each returned a single unbounded Arrow Table/RecordBatch to the Flight client. Once a result approaches the IPC layer's 2GiB-per-batch limit, Flight raises "Cannot send record batches exceeding 2GiB yet" and the request fails outright instead of degrading gracefully. Add module-level _split_oversized/_bounded_reader helpers that re-batch any Table or RecordBatchReader so no single RecordBatch exceeds 1.5GB, and route both do_get's RecordBatchStream and do_exchange's writer.write_batch loop through them. do_exchange is the newer HPA-safe read path (bae07fc) and was still writing one unbounded table via write_table, so it needed the same fix as do_get. Signed-off-by: dbbvitor <[email protected]> cosmic-ray's mutation run over the diff found one surviving mutant: `half = batch.num_rows // 2` mutated to `/`. A real pyarrow RecordBatch.slice() silently truncates a float offset/length to the same int, so no test built on real batches can observe the difference. Add a duck-typed fake batch that records the exact slice() call arguments and asserts they stay int, which does distinguish the two operators. Signed-off-by: dbbvitor <[email protected]> Extract to_arrow()'s metrics/audit finally-block into a reusable _emit_offline_store_request_metrics helper, and give every RetrievalJob a default to_arrow_reader() that wraps to_arrow(). This keeps every existing offline store working unchanged while giving stores that can page results natively (Trino, next) a hook to override without duplicating metrics code. Signed-off-by: dbbvitor <[email protected]> Add Query.start()/iterate_pages() to page through cursor.fetchmany()
instead of fetchall(), and override TrinoRetrievalJob.to_arrow_reader()
to consume them lazily. Jobs carrying on-demand feature views still use
the materialized to_arrow() path, since ODFVs need the full table.
Also fix trino_to_pa_value_type() to map "... with time zone" to a
tz-aware pa.timestamp("us", tz="UTC") instead of a tz-naive one, since
the cursor returns tz-aware datetimes for those columns.
Signed-off-by: dbbvitor <[email protected]>
Switch _execute_read_api's three read APIs, and do_exchange's get_historical_features branch, from to_arrow() to to_arrow_reader(). The default to_arrow_reader() makes this a no-op for every non-Trino store; Trino now streams instead of materializing the full result before the existing _bounded_reader (PR A) re-batches it for Flight. SQL errors still surface before the stream starts, since Query.start() executes eagerly. Cursor/temp-table cleanup on an early client disconnect is best-effort: RecordBatchReader.close() does not close the underlying generator. Signed-off-by: dbbvitor <[email protected]> Cosmic-ray found real gaps: the elapsed-time subtraction in both the metrics helper and to_arrow_reader() had no test pinning its exact value, so add/mul/mod/floordiv mutants survived; _stringify_complex's depth==0 check and its depth-1 recursion had no negative-depth or multi-level test to distinguish them from <=0 or >>1/%1/^1; and _complex_column_depth's trailing slice needed three levels of array nesting before an off-by-one became observable. Also drop the dead preserve_index=False kwarg from pyarrow.Table.from_pandas() in the Trino reader: since we always pass an explicit schema with no index field, pyarrow ignores preserve_index entirely for the table's data and public schema (verified empirically), so the argument was an untestable no-op rather than a missing test case. Signed-off-by: dbbvitor <[email protected]> Update the RetrievalJob functionality matrix in overview.md to match the per-store trino.md page: Trino now streams via to_arrow_reader(). Signed-off-by: dbbvitor <[email protected]>
dbbvitor
requested review from
ejscribner,
robhowley and
tokoko
and removed request for
a team
|
There was an error while loading. Please reload this page.
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@ ## master #6897 +/- ## ========================================== + Coverage 51.79% 51.93% +0.13% ========================================== Files 458 458 Lines 57715 57792 +77 Branches 8483 8494 +11 ========================================== + Hits 29896 30015 +119 + Misses 25793 25752 -41 + Partials 2026 2025 -1
Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
…ing-arrow-reader # Conflicts: # docs/reference/offline-stores/trino.md
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
Large Arrow results are fully materialized before use in three places (Flight, Trino, Spark)
There was an error while loading. Please reload this page.