Skip to content

fix: let the shm transport absorb the coordinator's plan_proto encode#30

Closed
mdashti wants to merge 20 commits into
moe/shm-on-protocol-grpcfrom
moe/shm-plan-proto-discard
Closed

fix: let the shm transport absorb the coordinator's plan_proto encode#30
mdashti wants to merge 20 commits into
moe/shm-on-protocol-grpcfrom
moe/shm-plan-proto-discard

Conversation

@mdashti

@mdashti mdashti commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

This PR makes the shm embedder work under the channel-protocol coordinator, which serializes every stage subplan into plan_proto before dispatch even though the shm channel ships plans over DSM and drains-and-discards that request.

Two changes, both under src/shm/, so #28 stays shm-only:

  • src/shm/plan_codec.rs adds ShmDiscardedPlanCodec, a PhysicalExtensionCodec the embedder registers via with_distributed_user_codec. It sits behind the built-in DistributedCodec in new_combined_with_user, so it is consulted only for nodes DataFusion's proto can't represent (custom scans, SortMergeJoinExec), and encodes each as empty. The bytes are never read, so it refuses to decode.
  • collect_task_metrics reports an empty task-level MetricsSet instead of None, so the unchanged decode_task_metrics accepts the shm path's frames and the per-task EXPLAIN rewrite runs.

Surfaced by the pg_search MPP regress in paradedb #5448: without the first, a SortMergeJoinExec query errored mid-dispatch (DataFusion's proto can't encode it and no codec absorbed it); without the second, joins showed no worker output_rows in EXPLAIN ANALYZE (every metrics frame failed to decode, so the rewrite timed out).

Stacked on #28. Draft for review.

gabotechs and others added 20 commits June 29, 2026 18:12
The worker-protocol abstraction shipped only a gRPC implementation, so
nothing exercised it without gRPC. This routes the three protocol methods
straight to a co-located `Worker`, and is the seam a shared-memory
transport plugs into. A worker resolves its own nested stage reads back
through the same transport, so multi-stage queries stay in process.
A co-located transport (in-process worker, shared-memory mesh) speaks the
same wire shape as gRPC, so the prost messages and the metrics codec have
to build with the feature off and crate::proto must resolve either way.
The plan-metrics collector and the receive-time stamp are the seams such a
transport drives directly.
The benchmarks dev-dependency and a few `tonic`-importing test helpers
re-unified gRPC into every test build, so nothing exercised the
in-process transport with gRPC off. Moving the dataset suites into the
benchmarks crate and gating the gRPC-coupled helpers lets
`cargo test --no-default-features --lib` run the in-process transport,
guarded by a new CI job.
Lets an embedder supply the dispatch bytes per stage instead of the
coordinator encoding the plan it holds, whose exec-time state can be
wrong to dispatch or not serializable through datafusion-proto.
An out-of-crate driver dispatches a query and drives the head stage itself,
so it needs prepare_in_process_plan, the metrics store and a public insert,
the partition-routing seam on NetworkBoundary, and a no-gRPC
decode_task_metrics to file proto metric frames into the plain store.
The shm ring/DSM/mesh/framing core moves verbatim from the fork; the old
WorkerTransport umbrella is gone, so the resolver hands out a channel and
execute_task reads the rings per partition. The mesh is the no-gRPC
transport, so it builds in both the grpc-on and grpc-off configs.
ShmWorkerChannel::coordinator_channel now ships each stage's
SetPlanRequest to the worker proc that owns its task, as a SetPlan frame
the worker takes with take_set_plan, so the embedder no longer routes
plans out of band.
The coordinator serializes every stage subplan before handing it to the
channel, but the shm transport ships plans over DSM and discards that
request. `ShmDiscardedPlanCodec` lets the throwaway encode succeed for
nodes DataFusion's proto cannot represent, such as `SortMergeJoinExec`.
The shm fragment path has no task-level stamps, but the decoder requires
the field present; emitting an empty set instead of `None` keeps every
worker metrics frame decodable so the per-task EXPLAIN rewrite runs.
@mdashti mdashti force-pushed the moe/shm-on-protocol-grpc branch from 992673d to ea63b5e Compare July 1, 2026 23:15
@mdashti mdashti force-pushed the moe/shm-plan-proto-discard branch from a09c34a to 741f0c1 Compare July 1, 2026 23:16
@stuhood stuhood force-pushed the moe/shm-on-protocol-grpc branch from ea63b5e to aa130c2 Compare July 6, 2026 22:22
@mdashti mdashti force-pushed the moe/shm-on-protocol-grpc branch from aa130c2 to 3f1137b Compare July 9, 2026 21:32
@mdashti

mdashti commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator Author

Closing: the passive-worker rework removed both halves of this PR. Workers no longer run the in-process nested dispatch, so there is no discarded plan_proto encode left for ShmDiscardedPlanCodec to absorb (the leader's DispatchPlanSource covers every stage, so the coordinator never falls back to encoding). The collect_task_metrics empty-set fix moved into #28.

@mdashti mdashti closed this Jul 9, 2026
@philippemnoel philippemnoel deleted the moe/shm-plan-proto-discard branch July 9, 2026 22:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants