Skip to content

Commit 3ccac30

Browse files
committed
feat(distributed): in_process_mode skips coordinator-to-worker gRPC plumbing
Adds `DistributedConfig::in_process_mode` (default false) and the `with_distributed_in_process_mode` / `set_distributed_in_process_mode` setters on `DistributedExt`. When set, `DistributedExec::prepare_plan` still walks every network boundary and converts `Stage::Local` to `Stage::Remote` with task→URL routing (so transports that key off `target_task` continue to work unchanged), but skips the per-worker gRPC plumbing: - `send_plan_task` (ships the worker subplan over the coordinator channel), - `metrics_collection_task` (background coordinator-channel reader for metrics), - `work_unit_feed_task` (work-unit-feed RPC). Intended for embedders that ship the worker plan over a side channel and provide their own [`WorkerTransport`] (e.g. a shared-memory mesh inside a single process). The URL recorded on `RemoteStage::workers` is meaningful to such transports only insofar as it indexes `target_task`; the transport is free to ignore the URL string. Default behaviour for users that don't set the flag is unchanged.
1 parent 5acc75a commit 3ccac30

3 files changed

Lines changed: 53 additions & 0 deletions

File tree

src/distributed_ext.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,15 @@ pub trait DistributedExt: Sized {
505505
/// Same as [DistributedExt::with_distributed_broadcast_joins_enabled] but with an in-place mutation.
506506
fn set_distributed_broadcast_joins(&mut self, enabled: bool) -> Result<(), DataFusionError>;
507507

508+
/// Skip the gRPC plan-send / metrics-collection / work-unit-feed tasks in
509+
/// `DistributedExec::prepare_plan`. Intended for embedders that ship the worker plan over a
510+
/// side channel and provide their own [crate::WorkerTransport]; input stages are still
511+
/// converted from `Local` to `Remote` so transport-keyed routing works the same way.
512+
fn with_distributed_in_process_mode(self, enabled: bool) -> Result<Self, DataFusionError>;
513+
514+
/// Same as [DistributedExt::with_distributed_in_process_mode] but with an in-place mutation.
515+
fn set_distributed_in_process_mode(&mut self, enabled: bool) -> Result<(), DataFusionError>;
516+
508517
/// The compression type to use for sending data over the wire.
509518
///
510519
/// The default is [CompressionType::LZ4_FRAME].
@@ -721,6 +730,12 @@ impl DistributedExt for SessionConfig {
721730
Ok(())
722731
}
723732

733+
fn set_distributed_in_process_mode(&mut self, enabled: bool) -> Result<(), DataFusionError> {
734+
let d_cfg = DistributedConfig::from_config_options_mut(self.options_mut())?;
735+
d_cfg.in_process_mode = enabled;
736+
Ok(())
737+
}
738+
724739
fn set_distributed_compression(
725740
&mut self,
726741
compression: Option<CompressionType>,
@@ -840,6 +855,10 @@ impl DistributedExt for SessionConfig {
840855
#[expr($?;Ok(self))]
841856
fn with_distributed_broadcast_joins(mut self, enabled: bool) -> Result<Self, DataFusionError>;
842857

858+
#[call(set_distributed_in_process_mode)]
859+
#[expr($?;Ok(self))]
860+
fn with_distributed_in_process_mode(mut self, enabled: bool) -> Result<Self, DataFusionError>;
861+
843862
#[call(set_distributed_compression)]
844863
#[expr($?;Ok(self))]
845864
fn with_distributed_compression(mut self, compression: Option<CompressionType>) -> Result<Self, DataFusionError>;
@@ -944,6 +963,11 @@ impl DistributedExt for SessionStateBuilder {
944963
#[expr($?;Ok(self))]
945964
fn with_distributed_broadcast_joins(mut self, enabled: bool) -> Result<Self, DataFusionError>;
946965

966+
fn set_distributed_in_process_mode(&mut self, enabled: bool) -> Result<(), DataFusionError>;
967+
#[call(set_distributed_in_process_mode)]
968+
#[expr($?;Ok(self))]
969+
fn with_distributed_in_process_mode(mut self, enabled: bool) -> Result<Self, DataFusionError>;
970+
947971
fn set_distributed_compression(&mut self, compression: Option<CompressionType>) -> Result<(), DataFusionError>;
948972
#[call(set_distributed_compression)]
949973
#[expr($?;Ok(self))]
@@ -1060,6 +1084,11 @@ impl DistributedExt for SessionState {
10601084
#[expr($?;Ok(self))]
10611085
fn with_distributed_broadcast_joins(mut self, enabled: bool) -> Result<Self, DataFusionError>;
10621086

1087+
fn set_distributed_in_process_mode(&mut self, enabled: bool) -> Result<(), DataFusionError>;
1088+
#[call(set_distributed_in_process_mode)]
1089+
#[expr($?;Ok(self))]
1090+
fn with_distributed_in_process_mode(mut self, enabled: bool) -> Result<Self, DataFusionError>;
1091+
10631092
fn set_distributed_compression(&mut self, compression: Option<CompressionType>) -> Result<(), DataFusionError>;
10641093
#[call(set_distributed_compression)]
10651094
#[expr($?;Ok(self))]
@@ -1176,6 +1205,11 @@ impl DistributedExt for SessionContext {
11761205
#[expr($?;Ok(self))]
11771206
fn with_distributed_broadcast_joins(self, enabled: bool) -> Result<Self, DataFusionError>;
11781207

1208+
fn set_distributed_in_process_mode(&mut self, enabled: bool) -> Result<(), DataFusionError>;
1209+
#[call(set_distributed_in_process_mode)]
1210+
#[expr($?;Ok(self))]
1211+
fn with_distributed_in_process_mode(self, enabled: bool) -> Result<Self, DataFusionError>;
1212+
11791213
fn set_distributed_compression(&mut self, compression: Option<CompressionType>) -> Result<(), DataFusionError>;
11801214
#[call(set_distributed_compression)]
11811215
#[expr($?;Ok(self))]

src/distributed_planner/distributed_config.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ extensions_options! {
4141
/// use broadcasting like checking build side size.
4242
/// For now, broadcasting all CollectLeft joins is not always beneficial.
4343
pub broadcast_joins: bool, default = false
44+
/// When set, `DistributedExec::prepare_plan` skips the gRPC plan-send / metrics-collection
45+
/// / work-unit-feed tasks. Tasks are still assigned to URLs (so input stages are still
46+
/// converted from `Local` to `Remote`), but no out-of-process worker is contacted.
47+
///
48+
/// Intended for embedders that ship the worker plan over a side channel and provide their
49+
/// own [crate::WorkerTransport] (e.g. a shared-memory mesh inside a single process). The
50+
/// transport receives the assigned URLs but is free to ignore them and route by
51+
/// `target_task` directly.
52+
pub in_process_mode: bool, default = false
4453
/// The compression used for sending data over the network between workers.
4554
/// It can be set to either `zstd`, `lz4` or `none`.
4655
pub compression: String, default = "lz4".to_string()

src/execution_plans/distributed.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@ impl DistributedExec {
170170
fn prepare_plan(&self, ctx: &Arc<TaskContext>) -> Result<PreparedPlan> {
171171
let worker_resolver = get_distributed_worker_resolver(ctx.session_config())?;
172172
let codec = DistributedCodec::new_combined_with_user(ctx.session_config());
173+
let in_process = DistributedConfig::from_config_options(ctx.session_config().options())
174+
.map(|c| c.in_process_mode)
175+
.unwrap_or(false);
173176

174177
let available_urls = worker_resolver.get_urls()?;
175178

@@ -236,6 +239,13 @@ impl DistributedExec {
236239
let mut workers = Vec::with_capacity(stage.tasks);
237240
for (i, routed_url) in routed_urls.into_iter().enumerate() {
238241
workers.push(routed_url.clone());
242+
if in_process {
243+
// Skip the coordinator → worker gRPC plumbing: the embedder ships the
244+
// worker plan over a side channel and exposes its own `WorkerTransport`.
245+
// The URL is still recorded on the `RemoteStage` so the transport can
246+
// key off `target_task` (the index into `RemoteStage::workers`).
247+
continue;
248+
}
239249
// Spawn a task that sends the subplan to the chosen URL.
240250
// There will be as many spawned tasks as workers.
241251
let (tx, worker_rx) = spawner.send_plan_task(Arc::clone(ctx), i, routed_url)?;

0 commit comments

Comments
 (0)