feat(rpc): Add core RPC types, client interface, and mock client [1/8] (OSS)#16645
Open
zhichenxu-meta wants to merge 1 commit intofacebookincubator:mainfrom
Open
feat(rpc): Add core RPC types, client interface, and mock client [1/8] (OSS)#16645zhichenxu-meta wants to merge 1 commit intofacebookincubator:mainfrom
zhichenxu-meta wants to merge 1 commit intofacebookincubator:mainfrom
Conversation
✅ Deploy Preview for meta-velox canceled.
|
|
@zhichenxu-meta has exported this pull request. If you are a Meta employee, you can view the originating Diff in D95008955. |
xiaoxmeng
approved these changes
Mar 5, 2026
xiaoxmeng
reviewed
Mar 5, 2026
Contributor
xiaoxmeng
left a comment
There was a problem hiding this comment.
@zhichenxu-meta you need to add cmake file?
Contributor
Author
|
zhichenxu-meta
added a commit
to zhichenxu-meta/velox
that referenced
this pull request
Mar 5, 2026
…] (OSS) (facebookincubator#16645) Summary: ## Stack Overview ### Problem Presto SQL queries need to call external services during execution — LLM inference, embedding generation, vector search, etc. These calls are high-latency (100ms–10s) and must be non-blocking so Velox pipelines stay productive. Today there is no framework for this in Velox; each service integration is built ad-hoc. ### User Experience Adding a new RPC function requires writing a single C++ file: ```cpp // 1. Implement the AsyncRPCFunction interface class MyRpcFunction : public AsyncRPCFunction { std::string name() const override { return "my_rpc_function"; } TypePtr resultType() const override { return VARCHAR(); } std::vector<RPCRequest> prepareRequests(...) const override { ... } VectorPtr buildOutput(...) const override { ... } std::shared_ptr<IRPCClient> getClient() const override { ... } }; // 2. Register with signatures (one line per alias) static AsyncRPCFunctionRegistrar __reg( "my_rpc_function", []() { return std::make_shared<MyRpcFunction>(); }, MyRpcFunction::signatures()); ``` That's it. The function is automatically: - Discovered by the native sidecar (`GET /v1/functions`) - Available in SQL by unqualified name (`SELECT my_rpc_function(...)`) - Intercepted by the Java planner and rewritten to an RPCNode - Executed asynchronously by the RPCOperator on workers No Java code changes needed. No hardcoded function name lists. ### Design Single-operator architecture: `TableScan -> RPCOperator -> downstream` The RPCOperator handles both dispatch (send) and join (receive) within one operator, using RPCState for async state management. It supports two streaming modes: - **PER_ROW**: Emit rows as they complete (low tail latency for high-variance workloads like LLM inference) - **BATCH**: Wait for all rows before emitting (lower overhead for uniform-latency workloads) Key components: per-tier rate limiting (RPCRateLimiter), pluggable RPC client interface (IRPCClient), and function registry with automatic sidecar discovery (AsyncRPCFunctionRegistry). ### Stack Contents - [1/8] Core types, client interface, mock client (OSS) - [2/8] RPCNode plan node and RPCState shared state (OSS) - [3/8] RPCOperator, RPCRateLimiter, RPCPlanNodeTranslator (OSS) - [4/8] Unit tests for core framework (OSS) - [5/8] AsyncRPC function registry and PlanTransformer (OSS) - [6/8] Production RPC clients and factory (Meta) - [7/8] Async RPC function implementation (Meta) - [8/8] Java planner, Presto protocol, plan converter (OSS) ## This Diff Defines the foundational types and interfaces for the RPC framework: - `RPCTypes.h`: `RPCRequest` and `RPCResponse` structs for passing data between the operator and RPC clients. `RPCStreamingMode` enum (PER_ROW vs BATCH). - `IRPCClient.h`: Abstract client interface with `call()` for single-row RPCs and `callBatch()` for batch RPCs, both returning `SemiFuture`. Default `callBatch()` fans out to individual `call()` invocations. - `AsyncRPCFunction.h`: Base class that function implementations extend. Provides `prepareRequests()` to convert input vectors into RPCRequests, `buildOutput()` to convert RPCResponses back into result vectors, and `getClient()`/`getBatchClient()` factory methods. - `MockRPCClient`: Test client with configurable latency, error injection, and echo behavior for unit testing. Reviewed By: xiaoxmeng Differential Revision: D95008955
c226cab to
3c4374f
Compare
…] (OSS) (facebookincubator#16645) Summary: ## Stack Overview ### Problem Presto SQL queries need to call external services during execution — LLM inference, embedding generation, vector search, etc. These calls are high-latency (100ms–10s) and must be non-blocking so Velox pipelines stay productive. Today there is no framework for this in Velox; each service integration is built ad-hoc. ### User Experience Adding a new RPC function requires writing a single C++ file: ```cpp // 1. Implement the AsyncRPCFunction interface class MyRpcFunction : public AsyncRPCFunction { std::string name() const override { return "my_rpc_function"; } TypePtr resultType() const override { return VARCHAR(); } std::vector<RPCRequest> prepareRequests(...) const override { ... } VectorPtr buildOutput(...) const override { ... } std::shared_ptr<IRPCClient> getClient() const override { ... } }; // 2. Register with signatures (one line per alias) static AsyncRPCFunctionRegistrar __reg( "my_rpc_function", []() { return std::make_shared<MyRpcFunction>(); }, MyRpcFunction::signatures()); ``` That's it. The function is automatically: - Discovered by the native sidecar (`GET /v1/functions`) - Available in SQL by unqualified name (`SELECT my_rpc_function(...)`) - Intercepted by the Java planner and rewritten to an RPCNode - Executed asynchronously by the RPCOperator on workers No Java code changes needed. No hardcoded function name lists. ### Design Single-operator architecture: `TableScan -> RPCOperator -> downstream` The RPCOperator handles both dispatch (send) and join (receive) within one operator, using RPCState for async state management. It supports two streaming modes: - **PER_ROW**: Emit rows as they complete (low tail latency for high-variance workloads like LLM inference) - **BATCH**: Wait for all rows before emitting (lower overhead for uniform-latency workloads) Key components: per-tier rate limiting (RPCRateLimiter), pluggable RPC client interface (IRPCClient), and function registry with automatic sidecar discovery (AsyncRPCFunctionRegistry). ### Stack Contents - [1/8] Core types, client interface, mock client (OSS) - [2/8] RPCNode plan node and RPCState shared state (OSS) - [3/8] RPCOperator, RPCRateLimiter, RPCPlanNodeTranslator (OSS) - [4/8] Unit tests for core framework (OSS) - [5/8] AsyncRPC function registry and PlanTransformer (OSS) - [6/8] Production RPC clients and factory (Meta) - [7/8] Async RPC function implementation (Meta) - [8/8] Java planner, Presto protocol, plan converter (OSS) ## This Diff Defines the foundational types and interfaces for the RPC framework: - `RPCTypes.h`: `RPCRequest` and `RPCResponse` structs for passing data between the operator and RPC clients. `RPCStreamingMode` enum (PER_ROW vs BATCH). - `IRPCClient.h`: Abstract client interface with `call()` for single-row RPCs and `callBatch()` for batch RPCs, both returning `SemiFuture`. Default `callBatch()` fans out to individual `call()` invocations. - `AsyncRPCFunction.h`: Base class that function implementations extend. Provides `prepareRequests()` to convert input vectors into RPCRequests, `buildOutput()` to convert RPCResponses back into result vectors, and `getClient()`/`getBatchClient()` factory methods. - `MockRPCClient`: Test client with configurable latency, error injection, and echo behavior for unit testing. Reviewed By: xiaoxmeng Differential Revision: D95008955
3c4374f to
2317377
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
Stack Overview
Problem
Presto SQL queries need to call external services during execution — LLM
inference, embedding generation, vector search, etc. These calls are
high-latency (100ms–10s) and must be non-blocking so Velox pipelines stay
productive. Today there is no framework for this in Velox; each service
integration is built ad-hoc.
User Experience
Adding a new RPC function requires writing a single C++ file:
That's it. The function is automatically:
GET /v1/functions)SELECT my_rpc_function(...))No Java code changes needed. No hardcoded function name lists.
Design
Single-operator architecture:
TableScan -> RPCOperator -> downstreamThe RPCOperator handles both dispatch (send) and join (receive) within
one operator, using RPCState for async state management. It supports two
streaming modes:
high-variance workloads like LLM inference)
uniform-latency workloads)
Key components: per-tier rate limiting (RPCRateLimiter), pluggable RPC
client interface (IRPCClient), and function registry with automatic
sidecar discovery (AsyncRPCFunctionRegistry).
Stack Contents
This Diff
Defines the foundational types and interfaces for the RPC framework:
RPCTypes.h:RPCRequestandRPCResponsestructs for passing databetween the operator and RPC clients.
RPCStreamingModeenum (PER_ROWvs BATCH).
IRPCClient.h: Abstract client interface withcall()for single-rowRPCs and
callBatch()for batch RPCs, both returningSemiFuture.Default
callBatch()fans out to individualcall()invocations.AsyncRPCFunction.h: Base class that function implementations extend.Provides
prepareRequests()to convert input vectors into RPCRequests,buildOutput()to convert RPCResponses back into result vectors, andgetClient()/getBatchClient()factory methods.MockRPCClient: Test client with configurable latency, error injection,and echo behavior for unit testing.
Reviewed By: xiaoxmeng
Differential Revision: D95008955