-
Notifications
You must be signed in to change notification settings - Fork 55
refactor: SessionConfig.extensions instead ConfigOptions.extensions #550
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 10 commits
fa3fb46
068b0da
ff757be
302551b
aa5231b
86635ce
93990e6
b4df221
6eab687
d495385
efb8121
65cf1f0
1ba1f5b
ffb4f23
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,9 @@ | ||
| use crate::distributed_planner::task_estimator::CombinedTaskEstimator; | ||
| use crate::protocol::ChannelResolverExtension; | ||
| use crate::work_unit_feed::WorkUnitFeedRegistry; | ||
| use crate::worker_resolver::WorkerResolverExtension; | ||
| use crate::{TaskEstimator, WorkerResolver}; | ||
| use datafusion::common::{DataFusionError, extensions_options, not_impl_err, plan_err}; | ||
| use datafusion::config::{ConfigExtension, ConfigField, ConfigOptions, Visit}; | ||
| use crate::config_extension_ext::register_config_extension_prefix; | ||
| use crate::config_extension_ext::set_distributed_option_extension; | ||
| use datafusion::common::{DataFusionError, extensions_options, plan_err}; | ||
| use datafusion::config::{ConfigExtension, ConfigOptions}; | ||
| use datafusion::execution::TaskContext; | ||
| use datafusion::prelude::SessionConfig; | ||
| use std::fmt::{Debug, Formatter}; | ||
| use std::sync::Arc; | ||
|
|
||
| extensions_options! { | ||
|
|
@@ -76,18 +72,6 @@ extensions_options! { | |
| /// If `dynamic_task_count` is enabled, this value is the amount of bytes/second each | ||
| /// partition is expected to handle. Lower values will result in greater parallelism. | ||
| pub bytes_per_partition_per_second: usize, default = 16 * 1024 * 1024 | ||
| /// Collection of [TaskEstimator]s that will be applied to leaf nodes in order to | ||
| /// estimate how many tasks should be spawned for the [Stage] containing the leaf node. | ||
| pub(crate) __private_task_estimator: CombinedTaskEstimator, default = CombinedTaskEstimator::default() | ||
| /// [ChannelResolver] implementation that tells the distributed planner information about | ||
| /// the available workers ready to execute distributed tasks. | ||
| pub(crate) __private_channel_resolver: ChannelResolverExtension, default = ChannelResolverExtension::default() | ||
| /// [WorkerResolver] implementation that tells the distributed planner information about | ||
| /// the available workers ready to execute distributed tasks. | ||
| pub(crate) __private_worker_resolver: WorkerResolverExtension, default = WorkerResolverExtension::not_implemented() | ||
| /// [WorkUnitFeedRegistry] that contains a set of getters that, applied to each node in a | ||
| /// plan, will return the [crate::WorkUnitFeed]s present in all nodes. | ||
| pub(crate) __private_work_unit_feed_registry: WorkUnitFeedRegistry, default = WorkUnitFeedRegistry::default() | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -100,19 +84,6 @@ fn cardinality_task_count_factor_default() -> f64 { | |
| } | ||
|
|
||
| impl DistributedConfig { | ||
| /// Appends a [TaskEstimator] to the list. [TaskEstimator] will be executed sequentially in | ||
| /// order on leaf nodes, and the first one to provide a value is the one that gets to decide | ||
| /// how many tasks are used for that [Stage]. | ||
| pub fn with_task_estimator( | ||
| mut self, | ||
| task_estimator: impl TaskEstimator + Send + Sync + 'static, | ||
| ) -> Self { | ||
| self.__private_task_estimator | ||
| .user_provided | ||
| .push(Arc::new(task_estimator)); | ||
| self | ||
| } | ||
|
|
||
| /// Gets the [DistributedConfig] from the [ConfigOptions]'s extensions. | ||
| pub fn from_config_options(cfg: &ConfigOptions) -> Result<&Self, DataFusionError> { | ||
| let Some(distributed_cfg) = cfg.extensions.get::<DistributedConfig>() else { | ||
|
|
@@ -121,12 +92,25 @@ impl DistributedConfig { | |
| Ok(distributed_cfg) | ||
| } | ||
|
|
||
| /// Gets the [DistributedConfig] from the [ConfigOptions]'s extensions. | ||
| pub fn from_config_options_mut(cfg: &mut ConfigOptions) -> Result<&mut Self, DataFusionError> { | ||
| let Some(distributed_cfg) = cfg.extensions.get_mut::<DistributedConfig>() else { | ||
| return plan_err!("DistributedConfig is not in ConfigOptions.extensions"); | ||
| }; | ||
| Ok(distributed_cfg) | ||
| /// Gets the [DistributedConfig] from the [SessionConfig], inserting a default if not present. | ||
| /// Always registers the `"distributed"` propagation prefix so coordinator-side settings are | ||
| /// included in gRPC headers sent to workers, regardless of call ordering. | ||
| pub fn from_session_config_mut(cfg: &mut SessionConfig) -> Result<&mut Self, DataFusionError> { | ||
| if cfg | ||
| .options() | ||
| .extensions | ||
| .get::<DistributedConfig>() | ||
| .is_none() | ||
| { | ||
| set_distributed_option_extension(cfg, DistributedConfig::default()); | ||
| } else { | ||
| register_config_extension_prefix(cfg, DistributedConfig::PREFIX); | ||
| } | ||
| Ok(cfg | ||
| .options_mut() | ||
| .extensions | ||
| .get_mut::<DistributedConfig>() | ||
| .unwrap()) | ||
| } | ||
|
Comment on lines
-124
to
99
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change also seems unrelated to this PR, ca we keep the
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, that way of injecting For ensuring that the impl SessionStateBuilderExt for SessionStateBuilder {
fn with_distributed_planner(mut self) -> Self {
let config = self.config().get_or_insert_default().options_mut();
config
.optimizer
.enable_physical_uncorrelated_scalar_subquery = false;
if config.extensions.get::<DistributedConfig>().is_none() {
config.extensions.insert(DistributedConfig::default());
}
let prev = std::mem::take(self.query_planner());
self.with_query_planner(Arc::new(DistributedQueryPlanner { prev }))
}
}But not sure if this is necessary.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reverted this change. There were some test breaking due to this but I resolved them by adding
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm afraid we cannot do that, because that means that in the same way this is blowing up in our tests here, it will blow up in other people's codebase, se we need to find an alternative. |
||
|
|
||
| /// Gets the [DistributedConfig] from the [ConfigOptions]'s in the provided [SessionConfig]. | ||
|
|
@@ -138,85 +122,8 @@ impl DistributedConfig { | |
| pub fn from_task_context(ctx: &Arc<TaskContext>) -> Result<&Self, DataFusionError> { | ||
| Self::from_session_config(ctx.session_config()) | ||
| } | ||
|
|
||
| /// Returns the [WorkerResolver] currently in scope for this [DistributedConfig]. | ||
| pub fn worker_resolver(&self) -> &Arc<dyn WorkerResolver> { | ||
| &self.__private_worker_resolver.0 | ||
| } | ||
| } | ||
|
|
||
| impl ConfigExtension for DistributedConfig { | ||
| const PREFIX: &'static str = "distributed"; | ||
| } | ||
|
|
||
| // FIXME: Ideally, both ChannelResolverExtension and TaskEstimators would be passed as | ||
| // extensions in SessionConfig's AnyMap instead of the ConfigOptions. However, we need | ||
| // to pass this as ConfigOptions as we need these two fields to be present during | ||
| // planning in the DistributedQueryPlanner, and the signature of the create_physical_plan() | ||
| // method there accepts a SessionState which only provides ConfigOptions. | ||
| // The following PR addresses this: https://github.com/apache/datafusion/pull/18168 | ||
| // but it still has not been accepted or merged. | ||
| // Because of this, all the boilerplate trait implementations below are needed. | ||
| impl ConfigField for ChannelResolverExtension { | ||
| fn visit<V: Visit>(&self, _: &mut V, _: &str, _: &'static str) { | ||
| // nothing to do. | ||
|
Rich-T-kid marked this conversation as resolved.
|
||
| } | ||
|
|
||
| fn set(&mut self, _: &str, _: &str) -> datafusion::common::Result<()> { | ||
| not_impl_err!("Not implemented") | ||
| } | ||
| } | ||
|
|
||
| impl Debug for ChannelResolverExtension { | ||
| fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||
| write!(f, "ChannelResolverExtension") | ||
| } | ||
| } | ||
|
|
||
| impl ConfigField for WorkerResolverExtension { | ||
| fn visit<V: Visit>(&self, _: &mut V, _: &str, _: &'static str) { | ||
| // nothing to do. | ||
| } | ||
|
|
||
| fn set(&mut self, _: &str, _: &str) -> datafusion::common::Result<()> { | ||
| not_impl_err!("Not implemented") | ||
| } | ||
| } | ||
|
|
||
| impl Debug for WorkerResolverExtension { | ||
| fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||
| write!(f, "WorkerResolverExtension") | ||
| } | ||
| } | ||
|
|
||
| impl ConfigField for CombinedTaskEstimator { | ||
| fn visit<V: Visit>(&self, _: &mut V, _: &str, _: &'static str) { | ||
| //nothing to do. | ||
| } | ||
|
|
||
| fn set(&mut self, _: &str, _: &str) -> Result<(), DataFusionError> { | ||
| not_impl_err!("not implemented") | ||
| } | ||
| } | ||
|
|
||
| impl Debug for CombinedTaskEstimator { | ||
| fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||
| write!(f, "TaskEstimators") | ||
| } | ||
| } | ||
|
|
||
| impl ConfigField for WorkUnitFeedRegistry { | ||
| fn visit<V: Visit>(&self, _: &mut V, _: &str, _: &'static str) { | ||
| //nothing to do. | ||
| } | ||
|
|
||
| fn set(&mut self, _: &str, _: &str) -> Result<(), DataFusionError> { | ||
| not_impl_err!("not implemented") | ||
| } | ||
| } | ||
|
|
||
| impl Debug for WorkUnitFeedRegistry { | ||
| fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||
| write!(f, "WorkUnitFeedRegistry") | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.